ASP.NET Core 10 REST API for time-locked letters, encrypted journal memories, and AI-generated reflective questions. Supports JWT authentication, email verification, offline sync, and SQLite or PostgreSQL (Supabase).
- Authentication — Register, login, email verification (OTP), password reset
- Letters — Create messages that unlock on a future date (AES-256 encrypted)
- Memories — Journal entries with images and emoji tags
- Questions — AI-generated reflection questions (Google Gemini), answered asynchronously via background worker
- Offline sync — Idempotent create using client-generated IDs
- Database — SQLite (local dev) or Supabase/PostgreSQL (production)
| Layer | Technology |
|---|---|
| Framework | ASP.NET Core 10 |
| ORM | Entity Framework Core |
| Auth | JWT Bearer |
| Docs | Scalar / OpenAPI |
| Logging | Serilog |
| Mapping | AutoMapper |
- .NET 10 SDK
- (Optional) Supabase project for PostgreSQL
- (Optional) Google Gemini API key for question generation
- (Optional) Gmail app password for SMTP (email verification)
git clone <your-repo-url>
cd WebApplication1
copy appsettings.Development.example.json appsettings.Development.jsonEdit appsettings.Development.json with your secrets (this file is gitignored).
Minimum values to set:
| Key | Description |
|---|---|
Jwt:Key |
At least 32 characters |
Encryption:Key |
Exactly 32 characters (changing it invalidates existing encrypted data) |
Gemini:ApiKey |
Required for AI questions |
Smtp:* |
Required for email verification and password reset |
For SQLite only (default), set "Database": { "Provider": "Sqlite" } in appsettings.json or Development config.
dotnet restore
dotnet run- API:
https://localhost:7261(seeProperties/launchSettings.json) - Scalar UI (Development):
https://localhost:7261/scalar
Migrations run automatically on startup when using SQLite in Development.
# Register
curl -X POST https://localhost:7261/api/auth/register `
-H "Content-Type: application/json" `
-d '{"username":"demo","email":"you@example.com","password":"Password123!","confirmPassword":"Password123!"}'Use the returned JWT in Authorization: Bearer <token> for protected endpoints.
| Setting | Default | Notes |
|---|---|---|
Database:Provider |
Sqlite |
Sqlite or Supabase |
ConnectionStrings:DefaultConnection |
Data\app.db |
SQLite path |
ConnectionStrings:SupabaseConnection |
— | PostgreSQL connection string |
Jwt:ExpirationMinutes |
10080 |
7 days |
See the documentation folder for API reference, architecture, and setup guides.
Controllers/ HTTP endpoints
Services/ Business logic (Interfaces + Implementations)
DTOs/ Request/response models
Domains/ EF entity models
Data/ DbContext and database files
Infrastructure/ Middleware, background workers, AutoMapper
Migrations/ EF Core migrations (SQLite)
docs/ Architecture, API, and module documentation
Properties/ Launch settings
SQLite (development)
dotnet ef database updateSupabase
Set Database:Provider to Supabase and apply schema manually (see docs/guides/supabase.md). EF migrations are intended for SQLite.
- Never commit
appsettings.Development.jsonor real API keys. - Rotate JWT, encryption, SMTP, and database credentials if they were ever committed to git.
- Letter and memory content is encrypted at rest with
Encryption:Key.
MIT (or add your preferred license)