Skip to content

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