Last1.app — Project Changelog¶
Work completed on the platform, sorted newest-first.
2026-02-10 — Phase 0: Governance + Platform Hygiene¶
Governance documents:
- Created standards/certification-levels.md — formal distinction between Last1 Verified and Last1 Certified levels
- Updated BUSINESS_STRUCTURE.md with founder compensation guardrail (IRS intermediate sanctions IRC §4958)
- Updated RealOutcomes language from "evaluates" to "analyzes" to reduce legal/defamation risk
Legal & branding alignment:
- Updated terms.tsx to reference Last 1 Enterprises, LLC (not Last1.org) as the service provider
- Updated privacy.tsx to reference Last 1 Enterprises, LLC as data controller
- Updated support.tsx with support@last1.app email
- Changed all legal contact emails from @last1.org to @last1.app
- Fixed invite URL fallback from last1.org to last1.app in server/routes.ts
Pricing & subscription alignment:
- Rewrote scripts/seed-products.ts with new 4-tier model (Starter/Pro/Certified/Coalition)
- Completely rewrote server/tierLimits.ts with expanded feature flags and tier aliases
- Rebuilt pricing.tsx as a modern SaaS pricing page with self-service checkout, annual/monthly toggle, and feature comparison table
Tier summary: - Starter: $0/mo (1 program, 25 beneficiaries, 50 SMS) - Pro: $99/mo or $950/yr (10 programs, 500 beneficiaries, 500 SMS) - Certified: $299/mo or $2,900/yr (unlimited, public verification page, certification mark) - Coalition: Custom $1K-3K/mo (cross-org, API, integrations, SLA)
2026-02-10 — Business Structure Definition¶
New document: docs/BUSINESS_STRUCTURE.md
- Defined Last1.org (501(c)(3) nonprofit) as standards body and certification authority
- Defined Last 1 Enterprises, LLC (for-profit) as the entity operating Last1.app and RadioCheck
- Established licensing relationship: 10% gross revenue from Last 1 Enterprises, LLC to Last1.org
- Set 4-tier pricing: Starter ($0), Pro ($99/mo), Certified ($299/mo), Coalition ($1K-3K/mo)
- Defined RadioCheck as a bundled feature of Last1.app, not a separate product
- Veterans and supporters always free; organizations pay through their tier
- Codified branding/verbiage rules for entity references across all pages
- Identified files requiring legal entity reference updates (terms, privacy, support)
- Committed to quarterly Transparency Reports (public revenue/cost disclosure)
- Positioned RealOutcomes as a separate future revenue stream under Last 1 Enterprises, LLC
- Included Year 1 and Year 2 revenue projections
2026-02-10 — Evidence Vault, Bulk Import, API Documentation¶
Evidence Vault (file uploads for outcome events):
- Added multer for multipart file handling (10MB limit, PDF/PNG/JPG/WEBP/DOC/DOCX)
- New endpoints: POST /api/evidence/upload, GET /api/evidence/:orgId/:fileId/:filename, DELETE /api/evidence/:orgId/:fileId/:filename
- Files stored in Supabase Storage evidence bucket
- Updated MilestoneCompletionDialog with drag-and-drop upload, progress indicator, and URL fallback toggle
Bulk Beneficiary CSV Import:
- Added papaparse for CSV parsing
- New endpoint: POST /api/beneficiaries/bulk with column alias mapping, per-row validation, tier limit enforcement
- New createBeneficiaries batch method in storage layer
- Created BulkImportDialog component (3-step: upload → preview → results) with downloadable CSV template
- Added "Import CSV" button to beneficiaries list page
API Documentation:
- Created docs/openapi.yaml — OpenAPI 3.0 spec covering ~40 endpoints across 12 domain tags
- Added swagger-ui-express + yamljs dependencies
- Mounted Swagger UI at /api/docs
2026-02-10 — Appeals & Remediation Backend¶
Database (3 new tables):
- appeals — Tracks appeal lifecycle (draft -> submitted -> under_review -> approved/denied/withdrawn)
- remediation_reviews — Tracks remediation reviews linked to orgs and appeals
- remediation_submissions — Individual submissions within a remediation review
- New enums: appeal_status, remediation_status
- Indexes on (organization_id, status) for both appeals and remediations
Storage layer (7 methods):
- getAppeals(), getAppealById(), createAppeal(), updateAppeal()
- getRemediationReviews(), createRemediationReview(), createRemediationSubmission()
API endpoints (7 routes):
- GET /api/org/appeals — List org's appeals
- GET /api/org/remediations — List org's remediation reviews
- GET /api/org/status — Get certification status + affected verification layers
- GET /api/org/appeals/eligibility — Check appeal eligibility (open appeals, recent decisions, active remediation)
- POST /api/org/appeals — Submit appeal with reasons and attachments (org admin only)
- GET /api/governance/appeals/:id — Get appeal detail (system admin only)
- POST /api/governance/appeals/:id/decision — Record decision with standard references (system admin only)
Business rules enforced: - Cannot appeal if status is active/none - Cannot appeal if open appeal already exists - Cannot appeal if remediation is in progress - 30-day cooldown after recent decision - Approved appeals restore certification to active + create history record - Denied appeals auto-create a remediation review - All actions create audit log entries
Validation schemas: createAppealSchema, appealDecisionSchema
Migration: migrations/20260210_appeals_remediation.sql
Files changed: shared/schema.ts, server/storage.ts, server/routes.ts, server/validation.ts, migration file
2026-02-10 — API Security Hardening¶
Rate Limiting & CORS
- Added express-rate-limit with tiered limits:
- General API: 100 req/min per IP
- Auth endpoints: 10 req/15 min per IP (brute-force protection)
- AI generation: 5 req/min per IP (cost protection)
- Configured cors middleware:
- Production locked to last1.app / www.last1.app
- Development open for local dev
- Credentials enabled, preflight cached 24h
Files changed: server/index.ts, package.json
2026-02-10 — Error Handling & Input Validation¶
Validation Middleware
- Created server/validation.ts with reusable validateBody(schema) Express middleware
- Defined 14 Zod update schemas for all PATCH endpoints
- All 15 PATCH routes now validate input before touching the database
- Strips unknown fields, returns structured error responses with field paths
Files changed: server/validation.ts (new), server/routes.ts
2026-02-10 — TypeScript Error Cleanup (21 errors -> 0)¶
Server fixes:
- server/customAuth.ts — Fixed 4 boolean | null assignment errors
- server/routes.ts — Fixed 7 errors (wrong method name, Date/string mismatches, missing required field, undefined guard)
- server/storage.ts — Fixed 3 errors (type casts, nonexistent properties on beneficiary model)
- shared/schema.ts — Removed duplicate UserRole type
Client fixes:
- AppealSubmissionForm.tsx — Fixed CertificationStatus export
- beneficiaries/[id].tsx — Fixed responseValue/responseText to use actual schema fields
- accept-invite/[token].tsx — Fixed useAuth import path
- pricing.tsx — Fixed invalid button variant
- programs/[id].tsx — Fixed outcome.name to outcome.description
Files changed: 9 files across server and client
2026-02-10 — Database Integrity Improvements¶
Schema changes (shared/schema.ts):
- Added "revoked" to certificationStatusEnum
- Created enrollmentStatusEnum (active, inactive, completed, withdrawn)
- organizations.bundleType now uses bundleTypeEnum instead of plain text
- programBeneficiaries.status now uses enrollmentStatusEnum
- organizationInvitations.role now uses userRoleEnum
Constraints added:
- Unique: organizationMembers(organizationId, userId)
- Unique: programBeneficiaries(programId, beneficiaryId)
- Unique: organizationInvitations.token
Cascade delete on 8 foreign keys (outcomes, check-ins, program_beneficiaries, service_logs, funding)
22 indexes added for query performance on FK columns, status fields, timestamps
Migration: migrations/20260210_database_integrity.sql
Files changed: shared/schema.ts, migrations/20260210_database_integrity.sql (new)
2026-02-09 — Testing Infrastructure¶
Setup:
- Created vitest.config.ts with V8 coverage for server/** and shared/**
- Added test scripts to package.json
- Updated CI workflow (.github/workflows/ci.yml) with test step
Test files created:
- server/__tests__/tierLimits.test.ts — 21 tests
- server/__tests__/planGuard.test.ts — 35 tests
- server/__tests__/webhookHandlers.test.ts — 12 tests
- server/__tests__/stripeClient.test.ts — 5 tests
- server/__tests__/schema.test.ts — 26 tests
- server/__tests__/validation.test.ts — 24 tests
Current total: 123 tests, 6 files, all passing
2026-02-08 — Railway Deployment & DNS¶
- Deployed to Railway with Docker
- Configured Cloudflare DNS for
last1.app - Updated Stripe webhook URL to
https://last1.app/api/stripe/webhook - Custom domain live and serving
2026-02-08 — Infrastructure Migration to Railway¶
Infrastructure decoupling:
- Removed all platform-specific packages and Vite plugins from the prior host
- Removed legacy host config files and the legacy server/integrations/ scaffolding
Service rewrites:
- server/twilio.ts — Decoupled from external connector, uses env vars
- server/sendgrid.ts — Decoupled from external connector, uses env vars
- server/stripeClient.ts — Removed external connector, uses STRIPE_SECRET_KEY
- server/webhookHandlers.ts — Removed legacy Stripe sync package, uses Stripe SDK directly
- server/stripeService.ts — Replaced DB queries to stripe.* tables with direct Stripe API calls
- server/customAuth.ts — Removed legacy dev-domain logic
- server/routes.ts — Updated imports, removed dead auth route stub
- vite.config.ts — Removed legacy host Vite plugins
Deployment artifacts created:
- Dockerfile (multi-stage, node:20-alpine)
- .dockerignore
- .github/workflows/ci.yml
- .env.example
Security fix: Removed .env from git tracking, advised key rotation
2026-02-06 — Phase 0: Standards & Identity Foundation¶
Documentation created (standards/):
- identity-model.md — Defines how organizations, programs, and outcomes are identified
- validation-layers.md — 5-layer verification framework
- certification-states.md — 4 certification states (Active, Conditional, Paused, Revoked)
- appeals-remediation.md — Non-punitive appeals process
- last1-standards.md — Master standards charter
- backlash-pressure-test.md — Adversarial scenarios and responses
- phase0-summary.md — Phase 0 executive summary