MyStreetzMag — Operational Manual
Version: 1.5
Last Updated: June 2026
Welcome to the MyStreetzMag operations handbook. This document explains how the site works, how to run it day-to-day, and how to handle every common task and edge case. Every section is paired with annotated screenshots — the numbers in each image map to a legend immediately below it.
1. The Big Picture
MyStreetzMag is an AI-assisted Afrobeats / Naija street culture magazine. The platform has two faces:
- Public site — readers come here for news (Music, News, Street Culture, Sports), articles, podcasts, playlists, interviews, videos, events, live radio with real-time now-playing, an AI music discovery chat, an artist submission portal, a community-stories feed, and a merch shop.
- Editor dashboard — you and your team approve AI-drafted content, review artist submissions, manage media, ingest RSS feeds, generate newsletters, view analytics, edit branding, and configure integrations.
The working model is:
AI prepares → Editor approves → Site publishes.
The AI never publishes anything to the public site on its own. Every article passes through a human approval step.
Legend — Public Landing
- Header — logo, navigation, "Submit Music" + "Listen Live" CTAs.
- Hero story — your top piece. Editors flip this with the HERO flag on any article.
- Newsletter section — readers subscribe here; submissions land in the Newsletter tab.
2. Admin Access
| Field | Value |
|---|---|
| Login URL | https://<your-domain>/admin/login |
admin@mystreetz.mag | |
| Password | streetz2026 (rotate it — see §11) |
Three steps to enter the dashboard: ① email → ② password → ③ SIGN IN. The login is JWT-based; sessions last 7 days.
3. Editor Dashboard — Tab by Tab
When you log in you land on /admin with thirteen tabs in the left sidebar.
3.1 ANALYTICS
The first thing you see. Shows:
- Articles Published / Total Views / Subscribers / Paid Orders — KPI tiles
- Submission Funnel — total, pending, approved, rejected
- Top Articles — your 10 most-viewed pieces
- By Category — counts and view totals per category
Use this daily to track what's working.
Legend — Analytics
- Sidebar tab marker — currently active tab is highlighted with a yellow left-bar.
- Title strip — confirms which tab you're on.
3.2 SUBMISSIONS
Every artist who fills out the public Submit form lands here. Each card shows:
- Artist name, genre, location, email
- The AI A&R review (score 1-10, verdict, profile, promo caption, recommendation)
- Buttons: LISTEN (opens their song link), APPROVE, REJECT
Approving a submission makes their public artist profile live at /artist/<id>.
Legend — Submissions
- Tab anchor — yellow bar shows you're on Submissions.
- Header — count of pending demos.
3.3 STORIES
Public visitors can submit their own personal stories at /story. They appear here as pending items with the author name, email, story title, body and any tags. The editor decides whether to approve, edit or reject each one — approved stories are surfaced on the public community feed.
Legend — Stories
- Sidebar tab — Stories. The list shows the newest pending submissions first.
3.4 ARTICLES
A table of every article — drafts, approved, published.
- Click + NEW ARTICLE (yellow, top-right of the table) to start a fresh empty draft. It creates the article in the database and immediately opens the editor so you can write headline, body, set cover image and tags from scratch — no AI step required.
- Click any title to open the Article Edit modal — full editor with headline, category, status, excerpt, body, cover image (URL + uploader), tags, SEO title, meta description, the ★ TOP STORY + TRENDING checkboxes, AND a live OG share preview pane on the right that refreshes ~500ms after every change. Toggle AUTO/COVER/BRAND inside the modal to see each layout instantly.
- Click PUBLISH to move a draft to live.
- Click ★ MAKE TOP STORY / ★ TOP STORY to add or remove the article from the homepage TOP STORY hero carousel. The yellow ★ badge in the title column shows which articles are currently the homepage Top Story.
- Click TREND / UNTREND to add or remove from the "Trending Now" rail on the homepage.
- Click WP to push the article to your connected WordPress site (requires WP credentials in §7).
- AI-drafted pieces are marked with a yellow AI badge. WP-pushed pieces have a red WP badge.
- OG SHARE column lets you pick how social previews look per article: AUTO (uses cover if present), COVER (force the cover-bg design), BRAND (force the brand-stripe fallback). Click PREVIEW to open the live 1200×630 PNG in a new tab.
How to change the homepage Top Story
The big rotating hero block at the top of / (labeled TOP STORY) is driven by every article whose hero flag is on. You can promote/demote in two equally valid ways:
- From the Articles table — find the row for the article you want and click MAKE TOP STORY (it turns yellow with a ★). Click again (now reading ★ TOP STORY) to demote it. You can have multiple Top Stories — they rotate in the hero carousel.
- From the Article Edit modal — click the article title, tick the ★ TOP STORY checkbox, then SAVE. This is the place to also fine-tune the cover image and excerpt that will appear on the hero — the modal's right pane shows you the live OG card so you can confirm before saving.
Tip: a great Top Story has (a) a big horizontal cover image (the hero crops to ~16:9), (b) a punchy headline ≤ 8 words, and (c) a 30-45 word excerpt. The hero carousel rotates through all hero=true published articles, so for a hard takeover demote everything else and leave only one ★.
Legend — Articles
- Sidebar tab — Articles.
- + NEW ARTICLE button — create a blank draft and jump straight into the editor.
- OG SHARE column — per-article social share card layout dropdown.
3.5 MEDIA
Manage podcasts, playlists, interviews, videos and events. Each item has a type, title, host/subject, duration, external URL, image, description and tags. They appear on the public site at /m/podcasts, /m/playlists, etc.
Legend — Media
- Sidebar tab — Media. Use the form to add a new piece; existing items appear in the list below.
3.6 PERSONALITIES
The yellow "Personalities" rail on the homepage is fully editable here. Add a name, role (Artist / DJ / Producer), and a photo URL (paste a link or use the inline uploader). Drag the order number to control left-to-right placement. Removing a personality deletes them from the public rail instantly.
Legend — Personalities
- Sidebar tab — Personalities. Add new at the top; existing list with edit/delete actions below.
3.7 RSS INGEST
Lists every RSS feed you've connected (NotJustOk is seeded by default).
- INGEST NOW — manually pulls 3 latest entries, sends each to Claude AI for a MyStreetz-voice rewrite, and saves them as drafts in the Articles tab for your approval.
- The system also auto-ingests every 2 hours in the background. Toggle this in SETTINGS → Auto RSS ingestion enabled.
Legend — RSS Ingest
- Sidebar tab — RSS Ingest. Each feed row has its own INGEST NOW button.
3.8 AI DRAFT
Paste any raw news, press release or rough notes. Click RUN AI DRAFT — Claude returns:
- a punchy MyStreetz-style headline,
- 30-45 word excerpt,
- 3-4 paragraph body,
- SEO title + meta description,
- 4-6 tags.
You can attach a featured image (uploaded to object storage), then click SAVE AS TRENDING DRAFT to put it in the Articles tab as a draft awaiting your final review.
Legend — AI Draft
- Sidebar tab — AI Draft.
- Raw input — paste press release / rough notes here.
- RUN AI DRAFT — Claude rewrites in MyStreetz voice.
3.9 NEWSLETTER
- Subscribers count tile.
- Digests Generated / Sent tiles.
- GENERATE WEEKLY DIGEST — Claude reads the last 14 days of published articles and composes a digest with a subject line, intro, themed sections and 6 featured stories.
- Each digest shows status (draft / sent). Click SEND on a draft to email all subscribers.
Without a Resend API key in Settings, sending only marks the digest as "sent" — no actual emails go out. With a key, it ships via Resend.
Legend — Newsletter
- Sidebar tab — Newsletter. Generate-and-send happens from the buttons in the cards above the digest table.
3.10 SHOP ORDERS
Every Stripe Checkout transaction. Shows created date, email, items, total, payment status. Stripe is in test mode by default — replace STRIPE_API_KEY in the backend .env with your live key to start taking real money.
Legend — Shop Orders
- Sidebar tab — Shop Orders. Status column: PAID, PENDING, or FAILED.
3.11 BRANDING
Edit the site's identity without touching code:
- Upload a new logo (replaces every appearance — header, footer, listen-live, admin sidebar, admin login).
- Upload a new favicon (the browser tab icon).
- Adjust Logo height (px).
- Adjust Hero headline / Section heading / Body / Nav font sizes (px). Leave blank to keep responsive defaults.
- SAVE BRANDING applies changes site-wide instantly. RESET TO DEFAULTS clears all overrides.
Legend — Branding
- Sidebar tab — Branding. Logo/favicon uploaders are at the top; font-size overrides below.
3.12 EDITORS
Manage your editorial team without ever opening the database.
- INVITE A NEW EDITOR — enter a name + email, click INVITE EDITOR. The system creates an editor account with a cryptographically random temporary password and emails a welcome message via Resend (subject line + login URL + manual PDF link). If Resend is in sandbox mode the API returns a friendly error and rolls back the half-created user.
- The CURRENT TEAM table lists everyone — admin and editors — with their role, join date, and a PW PENDING yellow flag if they haven't completed first-login password change yet.
- For editors with PW PENDING, a RESEND INVITE button regenerates the temp password and re-sends the welcome email (useful when the original landed in spam).
- REVOKE deletes the editor's account. Admin accounts are protected and cannot be revoked from this UI.
Legend — Editors
- Sidebar tab — Editors.
- Invite form — name + email → INVITE EDITOR.
3.13 SETTINGS
Configure integrations:
- Google Analytics — paste your GA4 Measurement ID (
G-XXXXXXXXXX). The site auto-injects the gtag script. - WordPress — site URL, admin username, Application Password (24 chars, 6 groups). Click TEST WP CONNECTION to verify before pushing articles.
- Resend — API key (
re_...) for newsletter sending + editor invites + forgot-password emails. Set a verified From email (MyStreetzMag <editor@yourdomain.com>) once your domain is verified at resend.com/domains. - Radio / Live Stream — see §5e for the full Radio chapter. Five fields:
- Radio Stream URL — your Icecast/Shoutcast
.mp3URL (or Mixcloud / SoundCloud / Spotify URL as a placeholder). - Currently On Air — manual override. Forces the red ON AIR badge + animated EQ. Not required if RadioDJ is pushing — any push within the last 5 min auto-flips the badge on.
- Now Playing label — free-text fallback (e.g. "DJ Kaywise · Afrobeats Street Mix"). Used only when no live metadata is available.
- Now Playing feed URL — JSON or RSS endpoint. The widget polls every 5s; backend caches each response for 5s. Auto-detects Icecast/Shoutcast/Centova/RadioKing/AzuraCast JSON shapes and standard RSS feeds.
- Radio push token — shared secret for the inbound
POST /api/radio/pushwebhook (RadioDJ / Centova / Liquidsoap can POST track changes to us in real time). Take this overrides the polled feed for 5 minutes after each push. Once a token is set, a copyable RadioDJ webhook config snippet appears under the field. - Auto RSS ingestion enabled — checkbox.
- Account Security — change your admin password from inside the app.
Forgot your password? On the /admin/login screen click Forgot your password?, enter your email and we'll send a single-use reset link via Resend. The link expires in 60 minutes. (Requires a configured Resend API key.)
Sensitive fields are masked on display. Indicators show CONFIGURED / NOT CONFIGURED / OFF.
Legend — Settings
- Sidebar tab — Settings.
- Account Security card — change the admin password. Current → New (≥8 chars) → Confirm → UPDATE PASSWORD. Backend rejects wrong current pw, too-short new pw, or same-as-current.
4. Publishing Workflow Quick Reference
Option A — Manual article
- Click AI DRAFT in admin.
- Paste your raw notes / press release.
- Click RUN AI DRAFT.
- Optionally attach a featured image.
- Click SAVE AS TRENDING DRAFT.
- Go to ARTICLES → find the draft → click PUBLISH.
- (Optional) click WP to mirror it to WordPress.
Option B — RSS ingest
- Go to RSS INGEST.
- Click INGEST NOW on a feed (or wait for the 2-hour auto-tick).
- Go to ARTICLES → review the new drafts (they all have the yellow AI badge and source
rss). - Click PUBLISH on the ones you want to ship.
Option C — Artist submission
- Artist fills out the public Submit form (
/submit) — they can paste a song link or upload an mp3 directly. - The AI A&R reviews their submission in seconds.
- You see it in SUBMISSIONS with the AI score and recommendation.
- Click APPROVE to make a public artist profile live at
/artist/<id>.
Newsletter lifecycle
5. Public Site Routes
| URL | What it shows |
|---|---|
/ | Homepage: hero, trending, listen-live, discover-more, personalities, newsletter, submission CTA |
/article/:slug | Single article with sharing-ready OG tags + JSON-LD schema |
/category/:name | All articles in a category (e.g. /category/Music, /category/Sports) |
/search?q=... | Full-text search across title/excerpt/body/tags |
/m/podcasts /m/playlists /m/interviews /m/videos /m/events | Media list pages |
/artist/:id | Approved artist's public profile |
/submit | Artist submission form with instant AI review |
/story | Public form where readers upload their own community stories |
/community | Public feed of approved reader-submitted stories |
/discover | AI music discovery chat |
/shop /shop/success | Merch store + Stripe success page |
/admin/login /admin/reset /admin | Editor area (no-indexed) |
Legend — Article Page
- Headline — Anton-display, brand-uppercase styling.
- Featured image — uploaded via AI Draft → Save flow.
Legend — Submit
- Form card — all artist demo fields.
- Submit button — fires the AI A&R review server-side; result appears on the same page.
Legend — Discover
- Input box — type any music question (
who sounds like asake?). - Send button — fires a Claude call; multi-turn session keyed by browser session.
Legend — Shop
- Product grid — 5 seeded products by default.
- Cart panel — appears once items are added. Click CHECKOUT WITH STRIPE.
Legend — Help (this page!)
- Download PDF — server-rendered via WeasyPrint, includes all of these screenshots.
- Print — clean print stylesheet (no header, no nav).
5b. Dynamic Social Share Cards
Every article auto-generates a branded 1200×630 PNG at /api/og/<slug>.png, used as the og:image for Twitter/Facebook/WhatsApp/IG previews. Editors can override the layout per article from the Articles → OG SHARE dropdown:
- AUTO — uses cover image if uploaded, falls back to brand stripe otherwise.
- COVER — force cover-bg design (with dark gradient + brand title overlay).
- BRAND — force brand-stripe fallback (red diagonal slash on black).
Legend — OG Card
- Category pill + title — auto-wrapped, auto-shrunk to fit.
- MyStreetzMag wordmark + tagline — always present for brand consistency.
5c. Ask MyStreetz — AI Omnisearch
The header ASK MYSTREETZ button (replaces the old search icon) opens an Apple-Spotlight-style modal that searches every article, media item and approved artist on the site. Powered by Claude AI:
- Live debounced search — results refresh ~450ms after you stop typing.
- AI synthesis — a 2-3 sentence answer at the top of the results, drawn ONLY from on-site content (the AI is instructed to never invent facts).
- Suggested follow-up questions — three Spotify-style "Try asking" chips that let you drill deeper with one click.
- Multi-word queries —
asake lagosmatches docs containing *any* of those words.
The same endpoint (POST /api/search/ai) powers any future surfaces — drop it on category pages, on/discover, or on a new homepage spotlight tile.
5d. The Mini Media Player (Spotify-style)
Anywhere on the public site, click a ▶ button on a podcast, playlist or interview card and a sticky mini-player anchors itself to the bottom of every page. It handles two playback modes:
- HTML5 audio — for any
media_urlending in.mp3,.m4a,.aac,.ogg,.wav,.flac. Includes a click-to-scrub progress bar, prev/next track buttons, and a QUEUE toggle that lists every playable item from the page you launched from. - Spotify embeds — paste any
https://open.spotify.com/track/…,/playlist/…,/album/…,/episode/…or/show/…URL in the Media admin form. The player renders Spotify's official 80px compact iframe inside the bottom bar — listeners can scrub, like, and add to library without leaving MyStreetz. - Everything else (YouTube, external sites, etc.) opens in a new tab.
The player stays alive as readers navigate between articles, so a podcast keeps playing while they browse.
5e. The Live Radio Widget (Now Playing)
The homepage Listen Live widget shows a red ON AIR badge, an EQ animation, a ▶ button that fires the global mini-player, and a NOW PLAYING line. The widget polls /api/radio/now-playing every 30 seconds; the backend resolves the answer using this precedence chain:
- Pushed track (RadioDJ / Centova / Liquidsoap →
POST /api/radio/push). Wins for 5 minutes after each push. - Polled feed (Settings → *Now Playing feed URL*). Auto-detects JSON or RSS; backend caches each response for 5 seconds to spare the upstream.
- Free-text fallback (Settings → *Now Playing label*).
A yellow LIVE METADATA chip appears on the widget whenever the source is push or feed (i.e. the song/artist line is *real*, not the static fallback).
Option 1 — Polled JSON / RSS feed (read-only)
Best when your radio host already exposes a public now-playing endpoint (most do).
- Find your host's now-playing URL. Common patterns:
- AzuraCast:
https://<your-host>/api/nowplaying/<station-id> - Icecast 2.x:
https://<your-host>/status-json.xsl - Centova:
https://<your-host>/cgi-bin/centovacast.cgi?action=affiliateCode&type=jsonor any/json/variant - RadioKing:
https://api.radioking.io/widget/radio/<your-radio>/track/current - Custom RSS: any feed whose latest
<item><title>isArtist - Song
- Paste it into Settings → Now Playing feed URL and Save Settings.
- The widget picks it up within 10s (5s widget poll + up to 5s backend cache). If the parser can't pull artist/song from your particular shape, the response is logged in
backend.err.logso we can extend the auto-detector.
Option 2 — Push from RadioDJ (real-time, recommended)
When you want zero-delay updates and full control over the payload — RadioDJ POSTs to us on every track change.
- In Admin → Settings → Radio → Radio push token paste a long random string (32+ chars). Save.
- A copyable RADIODJ WEBHOOK CONFIG snippet appears under the field with the exact URL, headers, and body template for your install.
- In RadioDJ → Config → Plugins → HTTP/Webhook (or your build's equivalent — *Notifications*, *Web Hooks*, etc.) configure:
```
URL: https://<your-domain>/api/radio/push
Method: POST
Headers: X-Radio-Token: <the-token-you-pasted>
Content-Type: application/x-www-form-urlencoded
Body: title=$title$&artist=$artist$&album=$album$&audio_url=$stream$
```
RadioDJ's variable tokens ($title$, $artist$, $album$, $stream$) are interpolated at runtime. The endpoint accepts JSON, form-urlencoded, multipart, and query-string payloads interchangeably, so you don't have to wrap RadioDJ's native key=value output in JSON — just send it raw.
- Save the plugin config. The next time a track loads, RadioDJ POSTs to MyStreetz, the widget shows the live ARTIST · SONG · ALBUM within 5 seconds, and the LIVE METADATA chip turns yellow.
Recognised body keys (case-insensitive — RadioDJ TitleCase $Title$ works the same as lowercase title):
| Key | Maps to | Notes |
|---|---|---|
title / Title / song / track | song title | At least one of these or artist is required |
artist / Artist | artist | |
album / Album | album | Optional |
audio_url | stream URL | Stored for the player; takes precedence over the static Stream URL when present |
cover | cover art URL | Stored for future widget upgrades |
duration | seconds | Optional, float |
Security notes
- The push token is treated as a secret — masked on every GET, never overwritten by an empty PUT. To rotate it, just paste a new value over the old one.
- Auth is timing-safe (
secrets.compare_digest). Wrong or missing token → 401. - A push expires after 5 minutes if no follow-up arrives, so a silent broadcaster gracefully falls back to the polled feed or the free-text line. There is no "stuck on yesterday's track" failure mode.
- The endpoint accepts
?token=...as an alternate to theX-Radio-Tokenheader for legacy RadioDJ builds that can't add custom headers (in that case put the token in the URL itself:…/api/radio/push?token=<your-token>).
Testing your config from a terminal
```bash
polled feed: confirm what the widget sees right now
curl -s https://<your-domain>/api/radio/now-playing | jq
push: simulate a RadioDJ form-urlencoded track change
curl -X POST https://<your-domain>/api/radio/push \
-H "X-Radio-Token: <your-token>" \
--data-urlencode "title=Lonely At The Top" \
--data-urlencode "artist=Asake" \
--data-urlencode "album=Work Of Art" \
--data-urlencode "audio_url=https://your-host:2020/8138/stream"
```
6. The AI Layer
All AI calls use Claude Sonnet 4.5 via the Emergent Universal LLM Key. You don't manage this key — it's set in the backend .env (EMERGENT_LLM_KEY). If quota runs low, top up at Profile → Universal Key → Add Balance inside the Emergent platform.
AI is used for:
- Article rewrites (RSS ingest + AI Draft tab)
- Artist A&R reviews (on every public submission)
- Music discovery chat (
/discover) - Weekly newsletter digest composition
- Ask MyStreetz omnisearch synthesis (
/api/search/ai) — answers natural-language questions from on-site content only
If an AI call fails, the system logs the error and falls back gracefully — the submission still saves (just without a review), the digest endpoint returns 500 (try again), the chat returns "Couldn't reach the AI".
7. Integrations Status & Setup
| Integration | Where to configure | How to test |
|---|---|---|
| Claude Sonnet 4.5 | Already live (Emergent key in backend .env) | Run AI Draft or chat |
| Object Storage | Already live (Emergent storage) | Upload a logo in Branding |
| RSS auto-ingest | Built-in (NotJustOk seeded). Toggle in Settings | Click INGEST NOW |
| Stripe | STRIPE_API_KEY in backend .env. Replace sk_test_… with sk_live_… to go live | Place a test order at /shop |
| Resend (newsletter) | Admin → Settings → Resend API key | Click SEND on a digest |
| Google Analytics | Admin → Settings → GA tracking ID | Open homepage in incognito, check GA realtime |
| WordPress publish-out | Admin → Settings → WP URL + Username + Application Password | Click TEST WP CONNECTION |
| Live Radio Now-Playing — pull | Admin → Settings → Now Playing feed URL (JSON or RSS) | Watch the homepage widget for 30s |
| Live Radio Now-Playing — push (RadioDJ) | Admin → Settings → Radio push token, then config RadioDJ HTTP plugin | curl the snippet shown under the token field |
8. SEO
Every page auto-generates:
- Dynamic
<title>and meta description - Canonical URL
- Open Graph + Twitter Card tags (rich previews on WhatsApp, X, Facebook, etc.) — using the dynamic OG cards described in §5b
- JSON-LD schema (NewsArticle on article pages, MusicGroup on artist profiles, NewsMediaOrganization on homepage)
System-level:
/robots.txt— allow all, disallow/adminand/api/api/sitemap.xml— auto-regenerated every request, lists every published article + media item + category
After deploying, submit https://<your-domain>/api/sitemap.xml to Google Search Console and Bing Webmaster Tools.
9. The Shop
- 5 seeded products (tee, hoodie, cap, tote, sticker pack).
- Customer adds to cart on
/shop, clicks CHECKOUT WITH STRIPE, completes Stripe Checkout, returns to/shop/success. - Test card:
4242 4242 4242 4242, any future expiry, any CVC. - Every order is logged in Admin → Shop Orders with status.
- Price calculation happens server-side from the product DB — frontend cannot tamper.
To add a product or change prices, today it requires a quick edit to /app/backend/seed.py followed by clearing the products collection. A products admin panel is on the roadmap.
10. The Newsletter
- Visitors enter their email on the homepage form (
/) — saved to MongoDB. - Admin → Newsletter → GENERATE WEEKLY DIGEST: Claude reads recent articles and composes a digest.
- Review the draft.
- Click SEND. If Resend key is configured, emails ship; otherwise the digest is marked sent locally.
You can subscribe-test by pasting your own email on the homepage — the system is idempotent (same email twice = single record).
11. Security & Maintenance
- Change the admin password from Admin → Settings → Account Security (no DB edit required).
- Keep
backend/.envout of source control (already in.gitignore). - WordPress and Resend keys live in the MongoDB
settingscollection — never in code. - The platform supports JWT rotation: changing
JWT_SECRETin backend.envinvalidates all sessions and forces re-login. - Monitor
/var/log/supervisor/backend.err.logfor runtime errors (especially around RSS scheduler ticks and AI calls).
12. Going Live Checklist
- [ ] Replace
STRIPE_API_KEYwith yoursk_live_…key. - [ ] Paste Resend API key in Settings.
- [ ] Paste GA4 Measurement ID in Settings.
- [ ] Configure WordPress credentials (correct URL + Application Password) and run TEST WP CONNECTION.
- [ ] Set
PUBLIC_SITE_URLin backend.envto your live domain (e.g.https://mystreetzmag.com). - [ ] Change the admin password (Settings → Account Security).
- [ ] Click Deploy in Emergent (deployment health check already passed).
- [ ] Submit sitemap to Google Search Console.
- [ ] Add a real favicon (32x32 PNG) via Admin → Branding.
- [ ] Verify the logo renders cleanly across header, footer, admin and admin login.
13. Troubleshooting
Articles aren't showing on the homepage.
Make sure their status is published (not draft) in Admin → Articles.
Trending Now rail is empty.
Click TREND on at least 4 published articles in Admin → Articles.
AI Draft button does nothing.
Check that the Emergent LLM key has balance. Profile → Universal Key → Add Balance.
WP publish button returns "WordPress credentials not configured".
Fill in URL + Username + Application Password in Settings, then click TEST WP CONNECTION.
Newsletter SEND says "0 sent".
You haven't pasted a Resend API key. Paste one in Settings.
Shop redirects to localhost on Stripe success.
Set PUBLIC_SITE_URL in backend .env to your real domain.
Site looks broken after font-size edit.
Admin → Branding → RESET TO DEFAULTS.
Search returns nothing.
The search hits title/excerpt/body/tags — try a broader query.
Social previews look wrong / show stale image.
Twitter/Facebook cache og:image. Use Twitter's Card Validator and Facebook's Sharing Debugger to force a refresh after changing the OG layout. The PNG itself is regenerated on every request server-side.
14. Day-to-Day Cadence (Suggested)
- Daily: Check Submissions, approve 1-3 best ones. Review RSS drafts, publish 2-3 a day.
- Weekly (Friday): Generate the Newsletter Digest and send.
- Weekly: Add 1-2 fresh podcasts/playlists/interviews under Media.
- Monthly: Review Analytics — what's trending? Adjust your editorial focus.
15. Where to Get Help
- This manual lives at
/helpon the live site and can be downloaded as PDF from there. - All credentials & keys: see Admin → Settings.
- Backend logs:
/var/log/supervisor/backend.err.log(ortail -fit). - Source repo: pushed to GitHub at
streetz-media-ai-final.
Appendix — Regenerating these screenshots
If the UI changes and the screenshots get stale, run:
```bash
/opt/plugins-venv/bin/python /app/scripts/build_manual_screenshots.py
```
This logs in with the seeded admin, captures every tab and public page, annotates with the numbered callouts you see above, builds the multi-panel lifecycle flows, and writes everything to /app/backend/manual_assets/. The /help viewer and PDF will pick up the fresh files automatically.
*Sound of the streets. Made with MyStreetzMag.*
