feat: add storage system with local disk and S3 providers

Introduces a provider-agnostic storage subsystem for file attachments.
Includes local disk and S3 backends, asset/attachment DB schemas, issue
attachment CRUD routes with multer upload, CLI configure/doctor/env
integration, and enriched issue ancestors with project/goal resolution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Forgotten
2026-02-20 10:31:56 -06:00
parent 32119f5c2f
commit fdd2ea6157
36 changed files with 1683 additions and 32 deletions

View File

@@ -45,6 +45,10 @@ export function resolveDefaultSecretsKeyFilePath(instanceId?: string): string {
return path.resolve(resolvePaperclipInstanceRoot(instanceId), "secrets", "master.key");
}
export function resolveDefaultStorageDir(instanceId?: string): string {
return path.resolve(resolvePaperclipInstanceRoot(instanceId), "data", "storage");
}
export function expandHomePrefix(value: string): string {
if (value === "~") return os.homedir();
if (value.startsWith("~/")) return path.resolve(os.homedir(), value.slice(2));
@@ -62,5 +66,6 @@ export function describeLocalInstancePaths(instanceId?: string) {
embeddedPostgresDataDir: resolveDefaultEmbeddedPostgresDir(resolvedInstanceId),
logDir: resolveDefaultLogsDir(resolvedInstanceId),
secretsKeyFilePath: resolveDefaultSecretsKeyFilePath(resolvedInstanceId),
storageDir: resolveDefaultStorageDir(resolvedInstanceId),
};
}

View File

@@ -5,6 +5,9 @@ export {
databaseConfigSchema,
loggingConfigSchema,
serverConfigSchema,
storageConfigSchema,
storageLocalDiskConfigSchema,
storageS3ConfigSchema,
secretsConfigSchema,
secretsLocalEncryptedConfigSchema,
type PaperclipConfig,
@@ -12,6 +15,9 @@ export {
type DatabaseConfig,
type LoggingConfig,
type ServerConfig,
type StorageConfig,
type StorageLocalDiskConfig,
type StorageS3Config,
type SecretsConfig,
type SecretsLocalEncryptedConfig,
type ConfigMeta,