feat: production-ready refactor — Neon PostgreSQL + Drizzle + multi-tenant RLS#1
Open
feat: production-ready refactor — Neon PostgreSQL + Drizzle + multi-tenant RLS#1
Conversation
- 3 shared primitives (NpHeadline, NpFigure, NpBar) enforce uniform anatomy - 10 typed cards: Article, Video, Quote, Credential, Press, Tech, Show, Gallery, CTA, Footer - Grid uses gap+background pattern for perfectly equal column widths - Single font (Space Grotesk) — hierarchy via size only, weight 500 max - Credential/Tech/Press cards with SILO-derived list patterns - EPKGrid rewritten as pure card composition — zero inline markup - Performance modes split into individual ArticleCards Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… columns Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…hTenant) Replaces SurrealDB client with node-postgres pool backed Drizzle client. withTenant() acquires a dedicated pool connection, sets app.tenant_id via set_config() for RLS, then resets and releases. docker-compose and drizzle.config updated to port 5433 to avoid conflict with existing local postgres on 5432. Both tests pass (tenant_id set / reset after execution). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generates full initial schema migration (0000) from drizzle-kit and adds custom RLS migration (0001) that enables + forces row-level security with tenant_id-scoped policies on all 24 tenant-scoped tables. Junction tables and the tenant table are correctly excluded. Verified isolation: non-superuser sees 0 rows from other tenant, 1 from own. Existing DB client tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…, connections, preflight) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move Twitter, Instagram, YouTube, and Gmail clients from src/clients/ to src/services/platform/ with three structural changes: - console.log/error replaced with createLogger() (stderr-safe, JSON) - getDb() and all SurrealDB writes removed — clients are now pure API - gmail.ts merges gmail-reader.ts + email.ts into one module; scanOutreachReplies() now takes domainToVenue as a parameter instead of loading it from DB, keeping the client dependency-free Barrel export at src/services/platform/index.ts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…, preflight, logistics, scheduler) 6 outreach modules migrated from SurrealDB to Drizzle ORM: - conversation.ts: thread assembly from email + outreach_reply tables - pipeline.ts: batch lifecycle (generate -> preview -> approve -> send) - intelligence.ts: event -> action dispatcher with logistics/cluster/conversation departments - logistics.ts: cost estimates and cluster analysis (pure functions + DB for cluster) - scheduler.ts: tour-to-pipeline bridge, uncontacted venue surveys - preflight.ts: fail-closed pre-send checks (daily limit, dedup, thread state) All SurrealDB getDb() calls replaced with Drizzle queries. tenantId parameter added to all functions. Logger replaces console.log/warn. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- src/services/content/drafter.ts — already existed; re-exported via barrel - src/services/content/duplicate-checker.ts — kept JSON-file index, replaced console.log with createLogger() - src/services/content/editorial-planner.ts — SurrealDB raw queries → Drizzle (post_draft, storyFragment, post tables); tenantId param; static fallback library retained - src/services/content/index.ts — barrel - src/services/analytics/instagram.ts — saveAudienceSnapshot / getLatestAudience / getAudienceHistory / getAudienceEvolution / getCorridorAnalysis - src/services/analytics/youtube.ts — saveYouTubeSnapshot / saveVideoCountryData / getLatestYouTubeSnapshot / getVideoCountriesForSnapshot - src/services/analytics/correlator.ts — 3-day email→views→visit→reply pattern; correlations stored as memoryLink rows (signalType='correlation') - src/services/analytics/index.ts — barrel Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…story/research stores) Replaces SurrealDB with Drizzle ORM across all calendar and memory modules. Adds tenantId to every function signature per multi-tenant architecture. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…, analytics, content, calendar, intelligence, system) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d plist Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New src/server/telegram.ts replaces inline DB queries and direct platform
instantiation with imports from src/services/. Uses createLogger("telegram"),
getDefaultTenantId() + withTenant() pattern, and proper tenantId threading
through all outreach service calls (runPipeline, getBatchStatus, getDailyLimits,
approveBatch, sendApprovedBatch, getConversationDashboard). Original
src/telegram-bot.ts left untouched.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pdate for new server Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract pure pillar helpers to src/services/content/pillars.ts (no DB dependency, fixes old src/core/pillar-helpers.ts → getDb chain) - Fix z.record() to z.record(z.string(), z.string()) in intelligence tools - Update platform clients to import from migrated duplicate-checker Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… toggle, YouTube player Replace pseudo-element column rules with SILO's native CSS Grid pattern: grid background bleeds through 1px gaps creating structural borders in both directions. Add font toggle (6 presets with x-height compensation), YouTube hover-to-unmute player with global audio unlock, Lenis smooth scroll, and scroll-reveal animations. Remove legacy section components in favor of card-based newspaper composition. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Old monoliths removed: mcp-server.ts (2083 lines), telegram-bot.ts (1338), core/ (2919), agents/ (6564), outreach/ (3863), analytics/ (1369), calendar/ (766), clients/ (2944), digital-department/ (905), content/ (279), old db helpers (3540), root files (2281), utils/ (603). 86 one-off scripts deleted (113 → 18). New architecture is self-contained: server/tools/ → services/ → db/ + lib/ + types/ Zero TypeScript errors. No circular dependencies. Types extracted to src/types/index.ts + src/types/analytics.ts. Email preview module spec added (planned, not implemented). CLAUDE.md updated to v9.0. TODO.md rewritten for current state. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Full production-ready refactor of flutur-ops MCP server:
FORCE ROW LEVEL SECURITYon all 24 tenant-scoped tables,withTenant()session-based isolationmcp-server.ts→ modularsrc/server/tools/*.ts(7 domain files) +src/services/(MCP-independent, testable)What changed
.surqlfilessrc/db/schema.ts(27 tables, 5 enums, 3 HNSW indexes)withTenant()session varsrc/services/(6 domains, reusable)console.logsecurityCLIVerification
Test plan
npx vitest run— 17/17 passnpx tsc --noEmit— 0 errors in src/{server,services,lib,config}/npx tsx scripts/migrate-from-surreal.tsto migrate live data🤖 Generated with Claude Code