No description
Feature A — Storage quota (1 GiB per family):
- src/lib/quota.ts: enforcement library with pure functions (fully unit-tested)
and DB-bound helpers; isPaidFamily() is the single payment abstraction gate
- src/lib/format-bytes.ts: extracted formatBytes() — safe for client imports
- POST /api/upload: quota check before presigned URL issuance (HTTP 402 + reason code)
- POST /api/memories/[id]/confirm: HeadObject reconciles actual R2 size; deletes
over-quota objects and marks row failed rather than silently exceeding limit
- GET /api/storage-usage: storage info endpoint for UI meter
- src/components/StorageMeter.tsx: meter bar + StorageQuotaBanner + MemberLimitBanner
- memories/page.tsx: quota banner, FAB disabled (⊘) when exceeded, compact meter in header
- settings/page.tsx: always-visible StorageMeter + MemberLimitBanner in invite section
Feature B — Member limit (2 per family, free tier):
- invites/route.ts: replaced ad-hoc inline check with checkMemberLimit() from quota lib
Structured 403 response: { reason, currentCount, limit }
- Freeze rule: paid→free downgrade leaves all members intact; only new invites blocked
Migration:
- drizzle/0007_subscription_status.sql: ADD COLUMN subscription_status varchar(20)
- debug-migration/route.ts: step added for hot-apply without full redeploy
- src/db/schema/family.ts: subscriptionStatus field added to Drizzle schema
Tests: 44 unit tests in src/__tests__/quota.test.ts, all passing
- Pure function tests (no DB): isPaidFamily, wouldExceedQuota, isAtMemberLimit, formatBytes
- DB-bound tests (mocked @/db): getFamilyStorageUsage, checkStorageQuota,
checkMemberLimit, getStorageInfo, tenant isolation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|---|---|---|
| docker/init-db | ||
| docs | ||
| drizzle | ||
| public | ||
| scripts | ||
| src | ||
| .dockerignore | ||
| .gitignore | ||
| CLAUDE.md | ||
| docker-compose.dev.yml | ||
| Dockerfile | ||
| drizzle.config.ts | ||
| next-env.d.ts | ||
| next.config.ts | ||
| package-lock.json | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| postcss.config.mjs | ||
| Project_tia.md | ||
| README.md | ||
| tsconfig.json | ||
| vitest.config.ts | ||
This is a Next.js project bootstrapped with create-next-app.
Getting Started
First, run the development server:
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
Open http://localhost:3000 with your browser to see the result.
You can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file.
This project uses next/font to automatically optimize and load Geist, a new font family for Vercel.
Learn More
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Learn Next.js - an interactive Next.js tutorial.
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
Deploy on Vercel
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more details.