Tema
/
Interneto svetainių serverio dalies kūrimas GO

Saugyklos sluoksnis ir dokumentų lentelė

Septyni failai kortelėse, iš apačios į viršų: saugyklos sluoksnis, tada lentelė, tada sujungimas. storage.golocal.go00004_documents.sqldocuments.sqlconfig.gohandlers.gomain.go.

1. internal/storage/storage.go (naujas) — Store sąsaja. Trys metodai, o paketo komentaras įvardija jungtį garsiai: tai ta pati forma kaip email.Sender, ir ji čia todėl, kad Railway konteinerio failų sistema laikina.

2. internal/storage/local.go (naujas) — LocalStore. Širdis yra Save: atverti failą, tada io.Copy(io.MultiWriter(f, h), r) — vienas perėjimas, maiša ir rašymas kartu. Įvykus bet kokiai kopijavimo ar užvėrimo klaidai, jis pašalina pusiau įrašytą failą, kad nepavykęs įkėlimas nepaliktų nieko. Open/Delete praleidžia raktą per safePath, kuri užtikrina keyPattern prieš jungdama jį prie bazinio aplanko. newKey — 16 atsitiktinių baitų kaip šešioliktainis.

3. db/migrations/00004_documents.sql (naujas) — documents lentelė:

owner_id     UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
file_hash    TEXT NOT NULL,                 -- SHA-256, šešioliktainis
storage_key  TEXT NOT NULL,                 -- neskaidrus raktas į saugyklą
status       TEXT NOT NULL DEFAULT 'draft'
             CHECK (status IN ('draft', 'sent', 'completed')),

status yra TEXT + CHECK, ne Postgres ENUM — aibė maža ir fiksuota, o išplėsti tikrinimo apribojimą vėliau lengviau nei daryti ALTER TYPE šokį. Gyvavimo ciklas — draft → sent → completed; šiandien viskas yra juodraštis. ON DELETE CASCADE reiškia, kad ištrynus vartotoją, jo dokumentai ištrinami kartu.

4. internal/db/queries/documents.sql (naujas) — kol kas dvi užklausos: CreateDocument (įterpimas, RETURNING *) ir ListDocumentsByOwner (WHERE owner_id = $1 ORDER BY created_at DESC). Savininkui apribotas skaitymas ir juodraščiu ribotas trynimas atkeliaus kitą pamoką. Paleisk sqlc generate ir atsiras tipizuoti CreateDocument/ListDocumentsByOwner metodai.

5. internal/config/config.go (keitimas) — du papildymai: UploadDir (UPLOAD_DIR, numatyta uploads) ir MaxUploadBytes (25 << 20). Komentaras pažymi Railway įspėjimą, kuriuo pasirūpinsi diegimo pamokoje — konteinerio diskas laikinas, todėl produkcijoje UploadDir nukreipiamas į primontuotą tomą.

6. internal/handlers/handlers.go (keitimas) — Handlers struktūra įgyja Store storage.Store lauką, o New jį priima. Grynas papildymas šalia praėjusios pamokos Mailer lauko.

7. cmd/signflow/main.go (keitimas) — sukonstruok saugyklą ir paduok ją New:

store, err := storage.NewLocalStore(cfg.UploadDir)
if err != nil {
	return err
}
log.Info("file storage: local disk", "dir", cfg.UploadDir)
h := handlers.New(cfg, queries, sessions, mailer, store, log)

NewLocalStore sukuria aplanką, jei jo nėra, tad pirmas paleidimas tiesiog veikia.