Skip to content

Dev local#30

Merged
Rowee13 merged 27 commits intomainfrom
dev-local
Apr 15, 2026
Merged

Dev local#30
Rowee13 merged 27 commits intomainfrom
dev-local

Conversation

@Rowee13
Copy link
Copy Markdown
Owner

@Rowee13 Rowee13 commented Apr 15, 2026

Description

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test coverage improvement

Related Issues

Closes #

Changes Made

Screenshots (if applicable)

Testing

  • All existing tests pass
  • Added new tests for the changes
  • Tested locally

Checklist

  • My code follows the project's code style
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published

Additional Notes

Rowee13 and others added 27 commits March 7, 2026 01:13
Dependabot auto-PRs are noisy and often fail with pnpm workspaces.
Security alerts remain enabled in repo settings for vulnerability
notifications. Dependencies will be updated manually as needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Slug auto-generates from project name by default (read-only).
Click "Customize" to edit independently for shorter email domains.
Click "Reset to auto" to re-sync with project name.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ephemeral per-session demo accounts with 1-hour TTL, L2 capability
(sandbox writes, no real SMTP), and an extensibility hook so future
tools in the deck can plug in their own seed data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
16 tasks across 4 phases: schema, demo module core, web UI, verification.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add isDemo to the Prisma select in both jwt and jwt-cookie strategies so
req.user.isDemo is populated for downstream guards (BlockDemo). Update the
JwtAuthGuard handleRequest TUser default to include isDemo: boolean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduce DemoSeeder interface and DemoSeederRegistry to coordinate
tool-specific demo data seeding. Uses a factory-based provider in
DemoModule so concrete seeders (DevInbox, future tools) can be appended
to the inject list without colliding on a shared DI token.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduces @BlockDemo() decorator and a globally-registered
BlockDemoGuard that rejects demo users on routes marked sensitive.
Applied to the change-password handler as the first protected route.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Throw UnauthorizedException when a @BlockDemo()-decorated route is hit
without req.user, instead of silently allowing. Removes dependence on
APP_GUARD ordering between JwtAuthGuard and BlockDemoGuard. Adds a
unit test for the missing-user case and documents the invariant on
the guard class.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds POST /api/auth/demo that creates a demo user (isDemo=true) with
a random unusable password, runs all registered DemoSeeders, and
issues JWT + refresh token via auth cookies. Gated by
DEMO_MODE_ENABLED (returns 404 when disabled) and rate-limited to
2 requests/hour.

Also opens AuthService.generateAccessToken/generateRefreshToken for
reuse and adds issueTokensForUser() for passwordless auth flows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Restore private visibility on generateAccessToken/generateRefreshToken
  in AuthService (same-class access from issueTokensForUser is legal).
- Wire DEMO_RATE_LIMIT_PER_HOUR into the @Throttle decorator literal
  and drop the unused DemoConfig.rateLimitPerHour getter.
- Add DemoController spec covering service wiring, token issuance,
  cookie setting, and expiresAt computation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds the first concrete DemoSeeder implementation, which creates a
"Demo Inbox" project and populates it with 5 clearly-fake sample
emails (welcome, password-reset, receipt, newsletter, attachment
reference) so new demo users have something to explore immediately.

- sample-emails.ts: 5 fixtures using example.com/.org addresses and
  href="#" placeholders. No real brands, URLs, tracking pixels, or PII.
- devinbox-demo.seeder.ts: suffixes the project slug with 6 chars of
  randomUUID() to sidestep the globally-unique slug constraint across
  multiple demo users.
- Attachment row intentionally not seeded — the 5th email references a
  pretend PDF in its HTML only, which is enough to exercise the inbox
  UI without wiring storage paths.
- demo.module.ts: extends the factory-based DemoSeederRegistry inject
  list to include the new seeder.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds POST /api/projects/:id/demo/inject-email for demo users to drop a
realistic fake email into one of their projects. Enforces:

- caller must have isDemo=true (else 403)
- project must be owned by the caller (else 404)
- cap of 20 injected emails per project (else 403)

Cap accounting uses a reserved `@inject.demo.local` sender domain rather
than a dedicated boolean marker column. Trade-off: no schema change and
self-documenting in DB inspection, at the cost of coupling cap semantics
to a magic-string domain. Seeded sample emails (RFC 2606
`@example.com`/`@example.org`) never collide with this count.

Ownership check is inlined as a single prisma.project.findFirst rather
than depending on ProjectsService, to keep DemoModule from importing
ProjectsModule.

Pool of 10 injectable templates (shipping, calendar, security, invoice,
mention, CI, magic link, product, survey, support) lives in
seeders/injectable-emails.ts; injectTestEmail picks one at random.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Was demo-inbox-<id>. Shorter slug makes the demo email address
(e.g. *@demo-abc123.<domain>) less visually cluttered in the UI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
So demo expiry redirect fires from any page, not only dashboard.
Body becomes flex-col so the banner docks above a flex-1 content area;
dashboard switches from h-screen to flex-1 min-h-0 to fill that slot.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Button inherited text color against white background, rendering
invisible. Explicit text-gray-700 matches the neutral palette.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Rowee13 Rowee13 merged commit a381dbb into main Apr 15, 2026
5 checks passed
@Rowee13 Rowee13 deleted the dev-local branch April 15, 2026 05:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant