Cloud: Cloud Functions for authoritative quota reconciliation and orphan GC
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 25/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Stack tecnologico
- firebase, typescript
Direzione di ricerca
Start with the existing Firebase workflows and emulator setup, then trace the manifest, Cloud Storage blob, and user content paths described in the issue. Use scripts/issue-review.py with the feat/cloud base when preparing the contribution. Done means reconciliation, orphan cleanup, admin triggering, emulator tests, CI deployment, idempotency, and the stated mutation coverage all pass.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
Add Cloud Functions that make usedBytes and fileCount authoritative rather than
client-reported, and garbage-collect orphaned data. This closes the residual gap knowingly left
open by #794.
Requires the Blaze plan.
The gap this closes
Client-side accounting plus security rules gets most of the way there: rules validate every
manifest write against limits read from users/{uid}, and Storage rules check current usage via
firestore.get() before permitting an upload. But a client that writes blobs to Cloud Storage
without updating its manifest can understate usedBytes. Only a server-side trigger observing
actual object events can settle the true number.
Scope
onObjectFinalized/onObjectDeletedtriggers onusers/{uid}/blobs/**that recompute and
write the authoritativeusedBytesandfileCountfor that user.- Orphan sweep: Cloud Storage blobs and
users/{uid}/content/{encPath}documents with no
corresponding manifest entry. These accumulate naturally when a flush partially fails, so this
is routine hygiene, not just anti-abuse. - A reconciliation path an admin can trigger for a single user from the admin panel.
- Deployment wired into the existing Firebase workflows, and functions runnable in the emulator so
tests do not need a live project.
Acceptance criteria
- Object finalize and delete triggers recompute authoritative
usedBytesandfileCount - A client that uploads a blob without updating its manifest is corrected within one trigger cycle
- Orphaned blobs with no manifest entry are swept
- Orphaned content documents with no manifest entry are swept
- The sweep never deletes data that a manifest still references
- Admin-triggered reconciliation for a single user works from the admin panel
- Functions run under the emulator; tests do not require a live project
- Functions deploy from CI
- Reconciliation is idempotent and safe to run repeatedly
- Scoped mutation coverage >= 80%
Implementation notes
- The trigger writes the same manifest document the client writes. Guard against clobbering a
concurrent client write — use a transaction and reconcile againstrev. - Beware trigger loops: a function writing the manifest must not cause a Firestore trigger that
writes again. - Deleting user data on account removal is a natural companion; scope it here or note it as a
follow-up. beforeUserCreatedblocking functions would let us reject unauthorized sign-ups before an Auth
record is even created, but they require an Identity Platform (GCIP) upgrade. Out of scope —
the rules-based gate in #789 is the accepted approach.
Depends on
- #794
Branching
This issue is part of the Cloud Accounts & Storage
milestone, which uses feat/cloud as its integration branch.
Branch from feat/cloud, and open the PR against feat/cloud. Never against main.
Create the branch (the --base flag also sets the default PR target for this branch):
gh issue develop <number> --base feat/cloud --checkout
Open the PR:
python3 scripts/issue-review.py <number> --base feat/cloud \
--summary "<summary>" --test-plan "<test-plan>"
feat/cloud merges to main in a single PR once the milestone is complete.
Why both flags are required: gh issue develop without --base branches from the repository
default branch (main), and scripts/issue-review.py falls back to main when --base is
omitted — both for the gh pr create target and for the changed-file list in the PR body.
- Lingua principale
- TypeScript
- Stelle
- 1
- Fork
- 0
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di jcollard/LuaInTheWeb
-
tech-debt
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
jcollard/LuaInTheWeb#752 ·
-
tech-debt
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 68/100
jcollard/LuaInTheWeb#690 ·
-
tech-debt
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 75/100
jcollard/LuaInTheWeb#590 ·
-
tech-debt
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
jcollard/LuaInTheWeb#518 ·
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
jcollard/LuaInTheWeb#235 ·
Tutte le issue di jcollard/LuaInTheWeb
Issue simili
-
`cf complete zsh >> .zshrc` fails on vanilla zshForse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
cloudflare/cf#340 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
-
Rename Madson cameraAperta
Difficoltà 2/5 Meno di un'ora Idoneità per principianti 75/100
StoDevX/AAO-React-Native#8785 ·
I maintainer di solito rispondono entro 1 giorno
-
Broken links in the docsAperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 75/100
-
bnv-manager-v2: accept_invite creates the Mailcow domain admin before the commitForse già presa @myOmikron l’ha presa oggi. Apertabug ready-for-agent
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100