Skip to content

Claude/review docs specs b up l0#6

Merged
Kilbas merged 3 commits into
mainfrom
claude/review-docs-specs-bUpL0
May 1, 2026
Merged

Claude/review docs specs b up l0#6
Kilbas merged 3 commits into
mainfrom
claude/review-docs-specs-bUpL0

Conversation

@Kilbas
Copy link
Copy Markdown
Owner

@Kilbas Kilbas commented May 1, 2026

No description provided.

claude added 3 commits May 1, 2026 16:26
- encryption.ts: AES-256-GCM, IV-prefixed (12B IV + 16B tag), base64; key
  from ENCRYPTION_KEY (32-byte hex); fails on missing/short key and on
  tampered ciphertext / IV / auth tag.
- llm.ts: Anthropic wrapper with generateJson({system, user, model, maxTokens}).
  System and user accept either a string or an array of content blocks with
  optional cache_control for §6.3 prompt caching. Maps Anthropic 429/5xx to
  TransientLLMError; re-throws other 4xx/non-API errors unchanged. Strips
  ```json``` fences before parsing. Plus validateLetterOutput() per §6.5
  (subject ≤80, body ≤2000, no HTML tags, reasoning non-blocking).
- search.ts: Brave wrapper searchCreator({displayName, instagramHandle, niche})
  with §6.1 query template; BraveUnavailableError distinct from "0 results".
- email-render.tsx: renderHtml({bodyText, trackingPixelId, baseUrl?}) using
  react-email; tracking pixel emitted only when id provided; baseUrl arg
  with APP_URL/NEXTAUTH_URL fallback.

Tests: 54 new unit tests (vitest), all mock fetch / SDK / env — no DB or
network. Pre-existing 6 Prisma DB-dependency suites continue to fail at
import (unchanged baseline from M1.1).

https://claude.ai/code/session_01Axdu8uRj62ccyQJtpRxhUu
M2.1 — Server module + API:
- src/server/briefs.ts: list, getBriefById, createBrief, updateBrief,
  archiveBrief. Permissions: any member creates/reads; edit+archive
  requires admin/owner OR original creator. All mutations write audit in
  the same transaction (brief.created/updated/archived).
- getBriefById resolves archived briefs by id — worker read path unaffected
  by archive flag (spec §5.2 archive behavior).
- Input validated via zod briefInputSchema: required fields, toneOfVoice
  enum, forbiddenPhrases element types, landingUrl http/https scheme check.
- API routes: GET+POST /api/briefs, GET+PATCH /api/briefs/[id],
  POST /api/briefs/[id]/archive. Body parsed as unknown + validated by
  server module (no unsafe casts). 500s log + return generic internal_error.

M2.2 — UI:
- /briefs list page with active/archived tabs, name/creator/created/status
  columns, "New brief" CTA.
- /briefs/new and /briefs/[id] edit pages with BriefForm component grouped
  into Identity, Product, Partnership, Style, Constraints, Optional sections
  per spec §8.1.
- Tone selector restricted to spec values; Archive button visible only to
  eligible users (server re-enforces).
- AppShell sidebar: added "Briefs" nav link (all members), per spec §8.3.

Tests: DB-dependent unit tests cover create defaults, required-field
validation, all permission matrix branches (member/admin/owner/creator),
cross-workspace IDOR (returns null, not Forbidden), archive idempotency,
archived-brief still resolvable by id, audit row assertions.

https://claude.ai/code/session_01Axdu8uRj62ccyQJtpRxhUu
M3.1 — Member SMTP:
- src/server/smtp-config.ts: testAndSaveMemberSmtp runs nodemailer
  transporter.verify() before any DB write; on failure throws
  SmtpConnectionError without persisting anything. On success encrypts
  password via @/lib/encryption (AES-256-GCM) and upserts member_smtp.
  Audits member_smtp.tested every save; member_smtp.configured only
  when row is new or non-credential fields changed.
- API: POST /api/profile/smtp/test, GET /api/profile/smtp (returns row
  without password fields). Verify timeout 10s.

M3.2 — Profile:
- src/server/profile.ts: getProfileForUser, updateDisplayName,
  changePassword (current-password verified before update),
  updateCalibration (toggle forcePreviewMode + reset counter; rejects
  empty patches; no audit per plan), getTodaySendCount per spec §7.5
  (created_at UTC, statuses approved|sending|sent).
- /profile screen: identity, password, SMTP, calibration counter +
  reset + force-preview toggle, today's send count read-only.
- Routes split: PATCH /api/profile (display name only),
  PATCH /api/profile/password (password only), PATCH /api/profile/calibration.

M3.3 — Workspace settings:
- src/server/workspace-settings.ts: getOrCreateSettings (race-safe
  upsert), updateSettings (admin/owner only, validates letterModel and
  summarizeModel allow-lists per §5.2, validates defaultBriefId exists
  in same workspace, audits workspace_settings.updated with from→to diff;
  no audit when patch is a no-op).
- /settings screen visible to all members; PATCH gated server-side;
  members see read-only form.
- AppShell: added Settings sidebar link (admin/owner only); Profile now
  accessed via UserMenu dropdown in header per spec §8.3.

Tests: DB-dependent unit tests cover all permission branches, encryption
round-trip, no-persist on verify failure, audit-event matrix, validation
rejections, default-brief cross-workspace check, and workspace isolation.
@Kilbas Kilbas merged commit 46299bf into main May 1, 2026
1 check failed
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.

2 participants