Files — the module and its seams

Files — the module and its seams An architecture diagram generated by Archify. file.Local (main) · Deps.Storage: contracts.Storage · Deps · its own contracts/, satisfied in main · Deps file.Local (main) Deps.Storage: contracts.Storage Deps a client module · Deps.Files: contracts.Opener · consumers · consumer a client module Deps.Files: contracts.Opener consumer admin shell · module.Nav only · no Resource · consumers · consumer admin shell module.Nav only · no Resource consumer contracts/ · File · 2 events · 2 permissions · Service · modules/file contracts/ File · 2 events · 2 permissions · Service module.go · Module(Deps{Storage, MaxBytes, QuotaBytes}) · modules/file module.go Module(Deps{Storage, MaxBytes, QuotaBytes}) internal/ · Service: Upload · Open · Delete · Reconcile · modules/file internal/ Service: Upload · Open · Delete · Reconcile httpx.Register · no rest.Spec · /api/v1/file/files · content · public/{id} · kit/ seams httpx.Register · no rest.Spec /api/v1/file/files · content · public/{id} admin screens · none · no Resource registered · kit/ seams admin screens none · no Resource registered events · file.uploaded · file.deleted → RemoveBlob · kit/ seams events file.uploaded · file.deleted → RemoveBlob jobs · file-reconcile · daily 03:45 · kit/ seams jobs file-reconcile · daily 03:45 migrations/000019_file · files · FORCE RLS · unique key · kit/ seams migrations/000019_file files · FORCE RLS · unique key Events · Permissions NewService · NewReconcile Routes: RegisterRoutes crud over Tx[Tenant] events.Publish sweep.Jobs() no Resource Deps.Storage contracts.Opener Nav only modules/file kit/ seams Deps · its own contracts/, satisfied in main consumers Legend Frontend Backend Database Message bus

Promises

  • • file:read guards the list, the record and a private download; file:manage the upload and the delete; a public file needs neither
  • • file.uploaded from Upload once the bytes are stored and the row written; file.deleted from Delete, carrying the storage key

Needs

  • • Storage is contracts.Storage, file.Local(cfg.Files.Dir) in main; MaxBytes zero is 25 MiB; QuotaBytes zero a GiB, negative none
  • • No rest.Spec: an upload is a stream, so the bytes go before the row; a delete removes the row and the bytes follow the event

Proof

  • • contracts/filetest: the fake and the real service pass one suite; internal tests prove both orders, the quota and the sweep
  • • module_test: 413 past the limit, a page is never inline, ranges and HEAD; app_test round-trips a file; no browser journey