# Codebase Context for Investigation ## Project Structure - **app/** - Phoenix LiveView application with blogs, user auth, editor dashboard - **blogex/** - Multi-blog engine library (Blogex) with NimblePublisher-based markdown posts ## Key Modules ### Blog Config (app/lib/firehose/blogs/) - `Firehose.EngineeringBlog` - blog_id: :engineering, base_path: "/blog/engineering" - `Firehose.ReleaseNotes` - blog_id: :release_notes, base_path: "/blog/releases" ### Blog Post System (blogex/lib/blogex/) - `Blogex.Post` - struct with fields: id, title, author, body, description, date, blog, image, tags, published - `Post.visibility(post)` returns :draft (published=false), :scheduled (future date), :live - `Post.days_until_live(post)` returns days until scheduled post goes live - Posts are compiled at build-time from markdown files in priv/blog/ ### Blog Module (blogex/lib/blogex/blog.ex) - `Blogex.Blog` - macro that uses NimblePublisher - `all_posts()` - returns published, non-future-dated posts (drafts excluded in prod) - `unfiltered_posts()` - returns ALL posts including drafts and future-dated - `recent_posts(n)` - returns n most recent published posts - `paginate(page, per_page)` - pagination support ### Registry (blogex/lib/blogex/registry.ex) - `Blogex.Registry.all_posts()` - all published posts across blogs - `Blogex.Registry.all_posts_unfiltered()` - all posts including drafts/scheduled - `Blogex.Registry.get_blog!(blog_id)` - get blog module by atom ### Router (app/lib/firehose_web/router.ex) - GET / - PageController.home (homepage with recent posts) - GET /blog/:blog_id - BlogController.index (blog listing) - GET /blog/:blog_id/:slug - BlogController.show (single post) - GET /blog/:blog_id/tag/:tag - BlogController.tag (posts by tag) - GET /api/blog/engineering - Blogex.Router (serves HTML+JSON+RSS) - GET /api/blog/releases - Blogex.Router (serves HTML+JSON+RSS) - LiveView: GET /editor/dashboard - EditorDashboardLive (authenticated) - LiveView: GET /microprints - MicroprintsLive ### Blogex Router (blogex/lib/blogex/router.ex) - Serves at /api/blog/{engineering,releases} - GET /feed.xml - RSS 2.0 feed - GET /atom.xml - Atom feed - These are mounted under /api/blog/* so feeds are at /api/blog/engineering/feed.xml ### Blog Controller (app/lib/firehose_web/controllers/blog_controller.ex) - Renders blog index, show, and tag pages using Phoenix templates with Blogex.Components - Uses the Phoenix layout (app.html.heex) with full UI ### Editor Dashboard (app/lib/firehose_web/live/editor_dashboard_live.ex) - Authenticated LiveView at /editor/dashboard - Shows Drafts and Scheduled posts tabs - Uses Blogex.Registry.all_posts_unfiltered() - Has a tab switcher between drafts and scheduled - Each post shows title, author, date, status ### Layout/UI (app/lib/firehose_web/components/layouts/app.html.heex) - Navbar with links to: Home, Blog, Releases, QWAN (external), Contact, theme toggle - No RSS icon/link visible in nav - No link to Editor Dashboard in nav (only accessible via direct URL) ### Homepage (app/lib/firehose_web/controllers/page_html/home.html.heex) - Shows intro text and recent posts grid (6 most recent across both blogs) ### Email/Mailer - `Firehose.Mailer` uses Swoosh with gen_smtp adapter - `Firehose.Accounts` has user registration, login, password change - `Firehose.Accounts.UserNotifier` for email notifications - No subscription/newsletter functionality exists ### Mix Dependencies - phoenix_live_view ~> 1.1.0 - swoosh ~> 1.16 (email library) - gen_smtp ~> 1.0 (SMTP adapter) - ecto_sql ~> 3.13, postgrex - blogex (path dependency, local)