Wrap-up of the multi-PR session that shipped account/quota/security work. Use this to pick up cleanly in the next session.
main)| PR | Closes | Brief |
|---|---|---|
| #62 | #52 | Jailbreak / root detection. flutter_jailbreak_detection, SecurityGate wraps runApp, IntegrityBlockedScreen for prod, warn-banner for staging, allow on local. Maestro flow .maestro/security/integrity_blocked.yaml. |
| #63 | #50 | Burned-in timestamp + GPS footer on every captured photo. New WatermarkService (pure function over bytes), LocationProvider, geolocator permission strings on iOS/Android. 10 unit tests covering footer-band darkness, timestamp variance, null-location fallback, decode-failure fail-closed. |
| #65 | #57, #58 (see note) | V10 migration: users.tier, users.email_verified, users.subscription_status/_provider/_external_id, with grandfather backfill. Tier enum (FREE 20/mo, PRO 500/mo, BUSINESS 5000/mo, ENTERPRISE unlimited). QuotaService + QuotaExceededException → 402 with snapshot in body. GET /api/v1/me. PhotoController calls assertCanUpload before MinIO. 7 QuotaServiceTest cases. |
| #68 | refs #53 | Cert pinning (sha256/<hex> over DER) on both Dio instances. Parser unit tests; SPKI upgrade noted as a #53 sub-task. |
| #74 | #71 | In-app account deletion (App Store 5.1.1(v)). Settings entry on Gallery AppBar → typed-confirmation screen → DELETE /api/v1/auth/me → clear secure storage → /login. Maestro flow .maestro/settings/delete_account.yaml runs last in the CI sequence (it destroys the test user). |
PR #65's body said Closes #57 and #58. GitHub recognised the first reference but not the second one after and — #58 is still listed open even though it's implemented. #57 is also still listed because the email-verification flow (the verify-email endpoint + SMTP wiring) wasn't shipped in this PR; only the schema + grandfather backfill. Treat #58 as effectively closed, #57 as partially done.
| PR | Status | Action |
|---|---|---|
| #61 | OPEN, mergeable=CONFLICTING | Has the format fix (2b3819b style: apply dart format to capture_camera_only_test.dart) but the merge state went dirty after #62/#63/#74 landed (gallery_screen.dart touched in #74, and pubspec.yaml/capture_screen.dart touched in #63). Rebase onto current main, push, merge. Contents are tiny — only capture_screen.dart comment + test/security/capture_camera_only_test.dart. |
PR #68 covered TLS pinning. Remaining sub-items, each its own future PR:
UIScreen.captured, Android FLAG_SECURE)local_auth)Blocked only by #61 merge. Same conceptual work — just a structural guard test against gallery picker.
/api/v1/me with the snapshot.billing.stripe block, pom.xml stripe-java dep) was left in a stash on the session machine because it depended on PR #65's User entity additions. Now that #65 is merged, that stash is safe to pop and finish: StripeWebhookController for customer.subscription.* and invoice.payment_*, CheckoutSessionController, BillingPortalController.email_verification_tokens table (Flyway V11)POST /api/v1/auth/verify/{token} + POST /api/v1/auth/resend-verification (rate-limited 1/min/email)email_verified == falseDependency chain:
#70 (Astro + Tailwind on Cloudflare Pages, marketing pages)
├── #72 (signup form → POST /api/v1/auth/register)
└── #73 (authenticated dashboard: gallery, billing, account)
depends on #59 for /dashboard/billing
backend change: CORS allow https://auditpic.com
Each is a separate, multi-day build. Recommend starting with #70's skeleton (one Astro starter PR with routing + placeholder pages, no copy decisions baked in) and iterating from there.
docs/auditPic/business/business-plan.md)ci-backend.yml only triggers on backend path changes (correct — saves CI minutes). But the build-push job is gated by if: github.event_name == 'push', so PRs validate tests but never run mvn clean package. A PR can pass tests while breaking the Docker image build — caught only after merge.
Fix: split build-push into:
build job — mvn clean package -DskipTests, runs on PR + pushpush job — Docker login + tag + push, runs only on pushSmall workflow edit, no logic change. Future-session PR.
dart format --set-exit-if-changed is a sharp edgeEvery Flutter PR this session tripped it. The local flutter analyze is permissive but the CI step is strict. Two cheap fixes:
dart format --set-exit-if-changed . pre-commit hook so it bites before push.make fmt target that runs the same command and document it in CONTRIBUTING.Multiple parallel sessions (other agent + this session) check out branches behind each other's back. Symptoms seen this session:
feat/security-hardening-phase1 landed on a local branch named fix/flutter-staging-baseurl.git checkout reported "Already up to date" on a branch with a different SHA on the remote.hotfix/tmp-volume-for-tomcat even though I had just git checkout -b feat/accounts-and-plans.Workaround for next session: when creating a PR branch, git checkout -B <branch-name> origin/main (capital B forces a reset) and git rev-parse --abbrev-ref HEAD to verify before each commit. Avoid trusting the working tree implicitly.
image_picker is still in pubspec.yaml#51 chose to lock the capture flow structurally rather than remove the dependency. Long-term, the camera-package migration in the security epic should drop image_picker entirely.
pubspec.yaml, capture_screen.dart, gallery_screen.dart after the three October merges; resolve trivially).Closes #57 and #58 only caught the first one).build-push job. 30-line workflow change./api/v1/me is already there.docs/auditPic/business/business-plan.mddocs/europeLogin/... (saved in memory as codemagic_new_app_runbook.md — also applies to AuditPic).maestro/{auth,gallery,capture,verification,security,settings}/*.yaml — wired into .github/workflows/maestro-ci.ymlCLAUDE.md § Port Registry)
Reacties