Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
run: |
IMAGE="${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/email-cleaner:${{ github.sha }}"
echo "IMAGE=$IMAGE" >> "$GITHUB_ENV"
gcloud builds submit --tag "$IMAGE" . --async
gcloud builds submit --tag "$IMAGE" .

- name: Deploy to Cloud Run
run: |
Expand Down
16 changes: 9 additions & 7 deletions PROJECT_STATE.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
# PROJECT_STATE.md

Last updated: 2026-01-18 02:35 CST — Commit: pending
Last updated: 2026-01-29 00:00 CST — Commit: pending

## 1. Technical Header (Snapshot Metadata)

PROJECT_NAME: Email Cleaner & Smart Notifications — Fastify Backend
SNAPSHOT_DATE: 2026-01-18 02:35 CST
SNAPSHOT_DATE: 2026-01-29 00:00 CST
COMMIT: pending
ENVIRONMENT: local

REPO_PATH: /Users/gil/Documents/email-cleaner/email-cleaner-fastify
BRANCH: main
BRANCH: develop
WORKING_TREE_STATUS: Dirty (modified files present)

RUNTIME: Node.js (Fastify)
Expand All @@ -27,7 +26,7 @@ LAST_VERIFIED_TESTS_DATE: 2026-01-18 02:35 CST
- OAuth flow validates `state`, issues `session_token`, and redirects to `${FRONTEND_ORIGIN}/auth/callback`.
- Auth middleware accepts session cookie or Bearer session JWT and sets `request.user`.
- `/api/v1/emails` returns raw Gmail emails without ML.
- `/api/v1/suggestions` enriches emails with ML suggestions and publishes domain events when threshold is met.
- `/api/v1/suggestions` enriches emails with ML suggestions, includes `snippet`, and publishes domain events when threshold is met.
- `/api/v1/notifications/summary` aggregates `NotificationEvent` records by period.
- Gmail OAuth client persists refreshed access tokens to the `Tokens` table.
- OAuth tokens are encrypted at rest using `TOKEN_ENCRYPTION_KEY`.
Expand Down Expand Up @@ -67,6 +66,8 @@ LAST_VERIFIED_TESTS_DATE: 2026-01-18 02:35 CST
- Gmail OAuth clients are created via `src/services/googleAuthService.js`.
- ML service integration via `src/services/suggestionService.js` and `src/services/mlClient.js`.
- n8n webhook listener exists (safe no-op).
- Gmail metadata defaults `category` to `unknown` when no label match is found.
- ML schema accepts missing `category` with default `unknown`.

---

Expand All @@ -88,7 +89,7 @@ LAST_VERIFIED_TESTS_DATE: 2026-01-18 02:35 CST
- Summary windowing uses `createdAt`; time zone alignment is not verified.

**Recent change:**
- No change in this snapshot (commit: pending).
- ML schema defaulted `category` and suggestions schema includes `snippet` (commit: pending).

### HU18 — Google OAuth session flow (backend)

Expand Down Expand Up @@ -120,10 +121,11 @@ LAST_VERIFIED_TESTS_DATE: 2026-01-18 02:35 CST

## 6. Next Immediate Action

➡️ Commit changes on `main`.
➡️ Commit Fastify fixes on a feature branch from `develop`.

---

## Version log

- 2026-01-18 02:35 CST — OAuth state, token encryption, and logging hardening (commit: pending)
- 2026-01-29 00:00 CST — ML schema default category + suggestions schema includes snippet (commit: pending)
4 changes: 2 additions & 2 deletions README_REENTRY.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@

## 1) Current snapshot (minimum that matters)

- Branch: `main`
- Branch: `develop`
- Latest checkpoint: `PROJECT_STATE.md`
- Backend tests: PASS (Jest, 13 suites / 47 tests)
- Backend tests: last verified PASS (Jest, 13 suites / 47 tests) on 2026-01-18
- Auth flow: Google OAuth validates `state`, sets httpOnly `session_token` cookie, and validates JWT via `authMiddleware`
- OAuth tokens are encrypted at rest (`TOKEN_ENCRYPTION_KEY`)
- Gmail client persists refreshed tokens to the `Tokens` table
Expand Down
2 changes: 1 addition & 1 deletion python/classifier/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Email(BaseModel):
from_: str = Field(..., alias="from")
date: str
isRead: bool
category: str
category: str = "unknown"
attachmentSizeMb: float

from datetime import datetime, timezone
Expand Down
2 changes: 2 additions & 0 deletions src/routes/suggestionRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const emailSuggestionSchema = {
from: { type: 'string' },
subject: { type: 'string' },
date: { type: 'string' },
snippet: { type: 'string' },
isRead: { type: 'boolean' },
category: { type: 'string' },
attachmentSizeMb: { type: 'number' },
Expand Down Expand Up @@ -56,6 +57,7 @@ export default async function (fastify, opts) {
from: "notificaciones@ejemplo.com",
subject: "Promoción especial",
date: "2024-07-01T12:00:00Z",
snippet: "Short preview of the email body.",
isRead: false,
category: "promotions",
attachmentSizeMb: 2.5,
Expand Down
2 changes: 1 addition & 1 deletion src/services/gmailService.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export class GmailService {
date: headers.date || '',
labels: msgData.data.labelIds || [],
isRead: !(msgData.data.labelIds?.includes('UNREAD')),
category: detectCategoryFromLabels(msgData.data.labelIds || []),
category: detectCategoryFromLabels(msgData.data.labelIds || []) || 'unknown',
attachmentSizeMb: msgData.data.sizeEstimate
? msgData.data.sizeEstimate / (1024 * 1024)
: 0,
Expand Down