| name | db-content |
| description | Database insertion via Prisma for MenFem content. Use when inserting articles, companies, culture picks, events, product reviews, explore features, or exchange listings into the database through conversational propose-approve-insert workflow. Trigger phrases include "insert article", "add to database", "create in prisma", "seed the database", or "populate the site". |
Database Content Insertion Skill
ABOUTME: Prisma-based content insertion workflow for all MenFem content types. ABOUTME: For writing/voice refinement, use content-refiner skill instead.
Overview
This skill enables programmatic content creation for all MenFem content types through a conversational propose-approve-insert workflow. Content is created through iteration, then inserted directly via Prisma.
This skill is for DATABASE INSERTION, not writing/drafting. For voice refinement, use content-refiner.
When to Use This Skill
Use this skill when:
- Inserting content into the database
- Populating the site with content
- User says "insert article", "add to database", "seed content"
- Auto-invoked by
/workfor tasks mentioning "insert", "database", "prisma"
NOT for:
- Writing/drafting content (use
/writingcommand) - Refining voice/structure (use
content-refinerskill)
Content Types Supported
| Trigger | Model | Required Dependencies |
|---|---|---|
insert article |
Article | Category |
insert company |
Company | Industry |
insert culture pick |
CulturePick + CultureWeek | Week (auto-created) |
insert event |
Event | None |
insert product review |
ProductReview | Brand |
insert explore feature |
ExploreFeature | None |
insert exchange listing |
ExchangeListing | SellerProfile |
Brand Context (Required Reading)
Before creating content, load MenFem brand context from docs/brand/:
| Document | Purpose |
|---|---|
storytelling.md |
Principles, villains, frameworks, voice |
writing-methodology.md |
Voice calibration, structure |
content-strategy.md |
Audience, content pillars |
Workflow
Step 1: Pre-Flight Check (First Run Per Session)
Audit current content and dependencies:
npx tsx -e "
import { prisma } from './src/lib/prisma'
const [articles, companies, culturePicks, cultureWeeks, events, productReviews, exploreFeatures, exchangeListings, categories, industries, brands, sellerProfiles] = await Promise.all([
prisma.article.count(),
prisma.company.count(),
prisma.culturePick.count(),
prisma.cultureWeek.count(),
prisma.event.count(),
prisma.productReview.count(),
prisma.exploreFeature.count(),
prisma.exchangeListing.count(),
prisma.category.findMany({ select: { id: true, name: true, slug: true } }),
prisma.industry.findMany({ select: { id: true, name: true, slug: true } }),
prisma.brand.findMany({ select: { id: true, name: true, slug: true } }),
prisma.sellerProfile.count(),
])
console.log('=== Content Counts ===')
console.table({ articles, companies, culturePicks, cultureWeeks, events, productReviews, exploreFeatures, exchangeListings })
console.log('=== Dependencies ===')
console.log('Categories:', categories.length > 0 ? categories.map(c => c.name).join(', ') : 'NONE - need to create')
console.log('Industries:', industries.length > 0 ? industries.map(i => i.name).join(', ') : 'NONE - need to create')
console.log('Brands:', brands.length > 0 ? brands.map(b => b.name).join(', ') : 'NONE - need to create')
console.log('Seller Profiles:', sellerProfiles)
"
Step 2: Propose Content
Present content in scannable format with all required fields.
Step 3: Wait for Approval
User responds:
- "looks good" / "yes" → Insert and publish
- "draft" → Insert unpublished
- "change X" → Revise and re-propose
- "skip" → Move to next
- "refine" → Invoke
content-refiner, re-propose
Step 4: Insert via Prisma
npx tsx -e "
import { prisma } from './src/lib/prisma'
const result = await prisma.[model].create({
data: { /* all fields */ }
})
console.log('Created:', result.id)
console.log('Slug:', result.slug)
console.log('Admin URL: /admin/[section]/' + result.id + '/edit')
"
Content Templates
Article
**Title:** [Under 200 chars]
**Slug:** [url-friendly]
**Category:** [Must exist]
**Excerpt:** [10-500 chars]
**Content:** [Markdown, 800-2500 words]
**SEO:** Meta title (60 chars), Meta description (160 chars)
Company
**Name:** [Max 200 chars]
**Slug:** [url-friendly]
**Industry:** [Must exist]
**Company Size:** [STARTUP / GROWTH / MIDSIZE / ENTERPRISE / PUBLIC]
**Content:** [Full profile]
Culture Pick
**Title:** [Max 200 chars]
**Category:** [One of 12 categories]
**Week:** [Monday date - auto-creates if missing]
**Description:** [Editorial context]
**Details:** [Category-specific JSON]
Event
**Title:** [Max 200 chars]
**Category:** [EXHIBITION / NETWORKING / LIVE_SHOW / POP_UP / PARTNERSHIP]
**Event Source:** [CURATED / PARTNERSHIP]
**Start/End:** [ISO datetime]
**Location:** [Venue and address]
Note: Event has no slug or publishedAt fields.
Product Review
**Title:** [Max 200 chars]
**Slug:** [url-friendly]
**Category:** [TECH / SOFTWARE / HARDWARE / PHYSICAL]
**Brand:** [Must exist]
**Content:** [Full review with ## sections]
Explore Feature
**Title:** [Max 200 chars]
**Slug:** [url-friendly]
**Type:** [EDITORIAL_FEATURE / MOOD_BOARD / COLLECTION / BUYING_GUIDE / TREND_REPORT]
**Content:** [Editorial markdown]
Exchange Listing
**Title:** [3-100 chars]
**Slug:** [url-friendly]
**Listing Type:** [DESIGN_ASSET / EDUCATIONAL / DIGITAL_ART / etc.]
**Price:** [In cents - 2900 = $29.00]
**Description:** [20-10,000 chars]
Note: Requires existing SellerProfile.
Field Name Gotchas
| Model | Wrong | Correct |
|---|---|---|
| ExploreFeature | featureType |
type |
| ExchangeListing | aiPrimaryTool |
primaryTool |
| ExchangeListing | aiCreationProcess |
creationProcess |
| Event | source |
eventSource |
| Company | size |
companySize |
| Event | slug |
(doesn't exist) |
Batch Creation
For multiple items, use scripts/temp-content.ts:
import { prisma } from '../src/lib/prisma'
async function createContent() {
const items = [/* array */]
for (const item of items) {
const existing = await prisma.model.findFirst({ where: { slug: item.slug } })
if (existing) {
console.log('⏭ Skipped:', item.slug)
continue
}
const result = await prisma.model.create({ data: { ...item, isPublished: true, publishedAt: new Date() } })
console.log('✓ Created:', result.slug)
}
await prisma.$disconnect()
}
createContent()
Run: npx tsx scripts/temp-content.ts
Quality Checklist
- Title present and within limits
- Slug is unique
- Required relationships exist
- No placeholder text
- Prices in cents (not dollars)
- Event dates in future
- Meta title < 60 chars
- Meta description < 160 chars