From somtech-somcraft-deployer
Déployer une instance SomCraft pour un client existant (migrations Supabase + Fly.io + skills). Orchestre 7 phases : pré-flight, plan, migrations, seed, déploiement, smoke tests, installation des skills. TRIGGERS : deploy-somcraft, déployer somcraft, installer somcraft, somcraft client, setup somcraft, upgrade somcraft, status somcraft
How this skill is triggered — by the user, by Claude, or both
Slash command
/somtech-somcraft-deployer:deploy-somcraftThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Déployer une instance SomCraft dédiée pour un client existant. Ce skill orchestre l'ensemble du processus en 7 phases.
Déployer une instance SomCraft dédiée pour un client existant. Ce skill orchestre l'ensemble du processus en 7 phases.
Ce skill supporte 3 modes selon la commande qui l'invoque :
install (défaut, depuis /deploy-somcraft) — Déploiement initial complet, toutes les phasesupgrade (depuis /deploy-somcraft-upgrade) — Saute pré-flight configuration, ne fait que migrations + redéploiementstatus (depuis /deploy-somcraft-status) — Lecture seule, rapporte l'état sans modifierDétecter le mode en lisant le prompt de l'utilisateur.
Référence détaillée : references/preflight-checks.md
.claude/CLAUDE.md (emplacement standard Somtech), puis CLAUDE.md à la racine en fallback. Extrais le nom du client (chercher "Client:", "Projet:", ou le titre H1)..mcp.json. Vérifie qu'il contient une entrée pour Supabase MCP avec un project_ref valide.fly.toml. Extrais :
app (nom de l'app Fly.io actuelle)primary_regionfly apps list si pas dans le toml)package.json existe (pas une validation stricte, juste confirmer qu'on est dans un repo Node).fly auth whoami. Si erreur, arrête et affiche : "Fly CLI non authentifié. Exécutez fly auth login."AskUserQuestion pour demander l'environnement cible :Question: "Sur quel environnement déployer SomCraft ?"
Options:
- staging : Environnement de développement/test
- production : Environnement de production client
{client} sur {env} ? (oui/non)"Si l'une de ces étapes échoue, arrête et affiche l'erreur clairement.
Avant de procéder, affiche un tableau récapitulatif :
| Item | Valeur |
|-------------------|------------------------------------------|
| Client | {client-name} |
| Slug | {client-slug} |
| Environnement | {env} |
| Supabase project | {project-ref} |
| Fly app | somcraft-{client-slug}-{env} |
| Fly org | {fly-org} |
| Image Docker | ghcr.io/somtech-solutions/somcraft:0.4.2 |
| Workspace initial | {client-name} - Docs |
| Admin email | (demandé à la prochaine étape) |
| Migrations | (détecté après clone) |
Demande confirmation finale avec AskUserQuestion :
Question: "Procéder au déploiement ?"
Options:
- oui, procéder : Lance toutes les phases
- annuler : Arrête ici
Référence détaillée : references/migrations-workflow.md
plugin.json :SOMCRAFT_VERSION=$(cat $PLUGIN_ROOT/.claude-plugin/plugin.json | jq -r .somcraftVersion)
TMP_DIR=$(mktemp -d)
git clone --depth 1 --branch v$SOMCRAFT_VERSION https://github.com/somtech-solutions/somcraft.git $TMP_DIR
ls $TMP_DIR/supabase/migrations/*.sql | sortmcp__supabase__execute_sql), lis supabase_migrations.schema_migrations pour détecter les migrations déjà appliquées.schema_migrations).mcp__supabase__apply_migration (OU mcp__supabase__execute_sql si apply_migration n'est pas disponible) en mode transactionnelschema_migrations avec son version (timestamp du nom de fichier)sc-{client-slug} via MCP Supabase :INSERT INTO storage.buckets (id, name, public)
VALUES ('sc-{client-slug}', 'sc-{client-slug}', false)
ON CONFLICT DO NOTHING;
sc_workspaces et sc_documents sont actives :SELECT tablename, rowsecurity FROM pg_tables WHERE tablename LIKE 'sc_%';
Toutes les tables doivent avoir rowsecurity = true. Sinon, afficher un warning.
IMPORTANT : Ne JAMAIS utiliser supabase db push --linked.
Référence détaillée : references/seed-workflow.md
AskUserQuestion :Question: "Quel email pour l'utilisateur admin de cette instance ?"
Options:
- admin@{client-slug}.com : Email générique par défaut
- Autre email : Saisir un email personnalisé
-- Via la table auth.users directement
INSERT INTO auth.users (id, email, encrypted_password, email_confirmed_at, raw_user_meta_data)
VALUES (gen_random_uuid(), '{admin-email}', crypt('{random-password}', gen_salt('bf')), now(), '{"role": "admin"}')
RETURNING id;
(Alternative : utiliser supabase.auth.admin.createUser() via un appel SDK si disponible.)
INSERT INTO sc_workspaces (name, slug, storage_bucket, created_by)
VALUES ('{client-name} - Docs', '{client-slug}-docs', 'sc-{client-slug}', '{admin-user-id}')
RETURNING id;
sk_live_<64-hex-chars>) :API_KEY="sk_live_$(openssl rand -hex 32)"
sc_workspaces :UPDATE sc_workspaces SET api_key = '{api-key}' WHERE id = '{workspace-id}';
INSERT INTO sc_workspace_members (workspace_id, user_id, role)
VALUES ('{workspace-id}', '{admin-user-id}', 'admin');
/tmp/somcraft-deploy-{client-slug}-credentials.txt pour l'afficher dans le rapport final.Référence détaillée : references/fly-deployment.md
FLY_APP="somcraft-{client-slug}-{env}"
fly apps list | grep "$FLY_APP"
Si elle n'existe pas, la créer :
fly apps create "$FLY_APP" --org "{fly-org}"
fly.toml temporaire depuis templates/fly-toml.tpl en remplaçant les variables.fly secrets set :fly secrets set \
ANTHROPIC_API_KEY="{anthropic-key}" \
NEXT_PUBLIC_SUPABASE_URL="https://{project-ref}.supabase.co" \
NEXT_PUBLIC_SUPABASE_ANON_KEY="{anon-key}" \
SUPABASE_SERVICE_ROLE_KEY="{service-role-key}" \
NEXTAUTH_SECRET="$(openssl rand -base64 32)" \
SOMCRAFT_MCP_API_KEY="{api-key-from-phase-3}" \
-a "$FLY_APP"
Note : Les secrets ANTHROPIC_API_KEY, les clés Supabase, etc., doivent être lus depuis le .env.local du projet client OU demandés interactivement via AskUserQuestion.
fly deploy -a "$FLY_APP" \
--image "ghcr.io/somtech-solutions/somcraft:$SOMCRAFT_VERSION" \
--config /tmp/fly-somcraft-{client-slug}.toml
fly status -a "$FLY_APP"
Retry jusqu'à 2 minutes (polling toutes les 10s).
Référence détaillée : references/smoke-tests.md
APP_URL=$(fly info -a "$FLY_APP" --json | jq -r .Hostname)curl -f "https://$APP_URL/api/health"
Attendu : 200 OK avec {"status":"ok"}
curl -X POST "https://$APP_URL/api/mcp/mcp" \
-H "Authorization: Bearer $SOMCRAFT_MCP_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Attendu : JSON avec la liste des tools MCP (doit inclure list_workspaces).
curl -X POST "https://$APP_URL/api/sc/documents" \
-H "Authorization: Bearer $SOMCRAFT_MCP_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"workspace_id\":\"$WORKSPACE_ID\",\"filename\":\"welcome.md\",\"type\":\"file\"}"
Attendu : 201 Created.
somcraft :
~/.claude/skills/somcraft/SKILL.md existeskills/somcraft/ du plugin vers ~/.claude/skills/somcraft/version: si présent, sinon comparer la date de modification)PLUGIN_SOMCRAFT_SKILL="$PLUGIN_ROOT/skills/somcraft"
TARGET_SOMCRAFT_SKILL="$HOME/.claude/skills/somcraft"
mkdir -p "$TARGET_SOMCRAFT_SKILL"
cp -r "$PLUGIN_SOMCRAFT_SKILL"/* "$TARGET_SOMCRAFT_SKILL/"
somcraft-{client-slug} :
$PLUGIN_ROOT/templates/project-skill.md.tplsed ou équivalent).claude/skills/somcraft-{client-slug}/SKILL.md du projet courantTARGET_DIR=".claude/skills/somcraft-{client-slug}"
mkdir -p "$TARGET_DIR"
sed \
-e "s|{{CLIENT_SLUG}}|{client-slug}|g" \
-e "s|{{CLIENT_NAME}}|{client-name}|g" \
-e "s|{{STAGING_URL}}|$STAGING_URL|g" \
-e "s|{{PROD_URL}}|$PROD_URL|g" \
-e "s|{{STAGING_SUPABASE_REF}}|$STAGING_REF|g" \
-e "s|{{PROD_SUPABASE_REF}}|$PROD_REF|g" \
-e "s|{{STORAGE_BUCKET}}|sc-{client-slug}|g" \
-e "s|{{FLY_ORG}}|$FLY_ORG|g" \
-e "s|{{FLY_APP_STAGING}}|somcraft-{client-slug}-staging|g" \
-e "s|{{FLY_APP_PROD}}|somcraft-{client-slug}|g" \
-e "s|{{WORKSPACE_ID}}|$WORKSPACE_ID|g" \
-e "s|{{WORKSPACE_NAME}}|{client-name} - Docs|g" \
-e "s|{{ADMIN_EMAIL}}|$ADMIN_EMAIL|g" \
-e "s|{{DEPLOY_DATE}}|$(date +%Y-%m-%d)|g" \
-e "s|{{SOMCRAFT_VERSION}}|$SOMCRAFT_VERSION|g" \
"$PLUGIN_ROOT/templates/project-skill.md.tpl" > "$TARGET_DIR/SKILL.md"
Afficher le rapport suivant :
════════════════════════════════════════════════════════
✓ SomCraft déployé pour {client-name}
════════════════════════════════════════════════════════
Environnement : {env}
Version : {somcraft-version}
URL : https://{app-url}
Workspace initial :
ID : {workspace-id}
Nom : {client-name} - Docs
Admin :
Email : {admin-email}
Password : {random-password}
⚠ Stocker dans 1Password : somcraft-{client-slug}-admin
API Key MCP :
{api-key}
⚠ Stocker dans 1Password : somcraft-{client-slug}-mcp
Skills installés :
✓ ~/.claude/skills/somcraft/ (global, v{plugin-version})
✓ .claude/skills/somcraft-{client-slug}/ (projet, v{plugin-version})
Prochaines étapes :
1. Stocker les credentials dans 1Password
2. Configurer votre .mcp.json local pour accéder à cette instance :
{
"somcraft-{client-slug}": {
"type": "http",
"url": "https://{app-url}/api/mcp/mcp",
"headers": { "Authorization": "Bearer <from-1password>", "Accept": "application/json, text/event-stream" }
}
}
3. Tester l'instance en ouvrant https://{app-url} dans un navigateur
4. Invoquer le skill 'somcraft-{client-slug}' pour toute opération future
════════════════════════════════════════════════════════
Si le mode est upgrade :
.claude/skills/somcraft-{client-slug}/SKILL.mdSi le mode est status :
.claude/skills/somcraft-{client-slug}/SKILL.mdfly status -a {app-staging} et fly status -a {app-prod}npx claudepluginhub somtechsolutionmaxime/somtech-pack --plugin somtech-somcraft-deployerFetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Applies a firm's KYC/AML rules grid to parsed onboarding records: assigns risk rating, checks required documents, outputs rule outcomes with citations, and routes for escalation.
Generates daily or weekly digests of activity from connected sources (chat, email, docs, tasks, CRM), highlighting action items, decisions, mentions, and project updates.