fix(glossary): eliminate all redundant elements - filter imported templates, remove duplicate buttons and links
Some checks failed
Deploy to Production / Build and Deploy (push) Has been cancelled

This commit is contained in:
2026-06-20 19:03:44 +02:00
parent 489df66c0f
commit 4a8f33d36f
2 changed files with 214 additions and 33 deletions

View File

@@ -0,0 +1,206 @@
# Innovation Strategy: office_translator (Wordly.art)
**Date:** 2026-06-13
**Strategist:** Sepehr
**Strategic Focus:** Identifier comment transformer la préservation parfaite du format Office (aujourd'hui un avantage technique) en un positionnement de marché défendable et un modèle d'affaires scalable, face à des acteurs comme DeepL (qui copie déjà ce créneau) et Google (qui peut le copier à tout moment).
---
## 🎯 Strategic Context
### Current Situation
**Produit technique mature, pré-lancement commercial.**
- Stack production-ready : FastAPI + Next.js 15 + PostgreSQL + Redis + Docker, déployé en self-hosted
- Différenciateur technique central et vérifiable : **préservation de la mise en forme complexe Excel/Word/PowerPoint** (formules, fusions, styles, images, headers/footers, animations) — c'est le *seul* vrai fossé concurrentiel selon ton positionnement
- Architecture multi-providers déjà en place (Google, DeepL, OpenAI, Ollama, DeepSeek, OpenRouter, LibreTranslate, WebLLM en navigateur) — flexibilité réelle mais risque de dilution du message
- Capacités secondaires existantes : self-hosting, WebLLM zero-data, vision pour images dans Excel, glossaires techniques
- Infrastructure monétisation prête (Stripe) mais **pas encore de clients payants actifs** documentés
- Tarification définie : Free / Starter $9 / Pro $29 / Business $79
- Marketing plan rédigé mais assets visuels (captures, vidéo démo) non produits
- Faiblesses techniques identifiées (credentials en dur, stockage JSON, CORS permissif, pas de Celery)
### Strategic Challenge
**Le défi stratégique central : la préservation du format est un avantage technique reproductible.**
DeepL a déjà empiété sur ce territoire et Google peut le cloner en quelques trimestres. Ton avantage actuel est *technique* (comment tu traduis), pas *positionnel* (où tu te places dans l'esprit du client). Trois sous-défis critiques :
1. **Quel segment précis est prêt à payer significativement plus pour la préservation du format ?** (Pas "tout le monde qui traduit des documents" — c'est trop large et DeepL/Google les servent déjà.)
2. **Quel modèle d'affaires verrouille cet avantage** au point que même un clone gratuit de Google ne puisse pas te déloger ? (Self-hosting enterprise ? Vertical spécialisé ? Données/apprentissage ? Communauté ?)
3. **Quel "job to be done" non-traduction ton outil accomplit-il déjà** et que tu n'exploites pas encore commercialement ? (Compliance ? Archivage multilingue ? Workflow documentaire intégré ?)
Sans réponse tranchée à ces trois questions, tu risques d'être un excellent produit technique avec une proposition de valeur diluée.
---
## 📊 MARKET ANALYSIS
### Market Landscape
{{market_landscape}}
### Competitive Dynamics
{{competitive_dynamics}}
### Market Opportunities
{{market_opportunities}}
### Critical Insights
{{market_insights}}
---
## 💼 BUSINESS MODEL ANALYSIS
### Current Business Model
{{current_business_model}}
### Value Proposition Assessment
{{value_proposition}}
### Revenue and Cost Structure
{{revenue_cost_structure}}
### Business Model Weaknesses
{{model_weaknesses}}
---
## ⚡ DISRUPTION OPPORTUNITIES
### Disruption Vectors
{{disruption_vectors}}
### Unmet Customer Jobs
{{unmet_jobs}}
### Technology Enablers
{{technology_enablers}}
### Strategic White Space
{{strategic_whitespace}}
---
## 🚀 INNOVATION OPPORTUNITIES
### Innovation Initiatives
{{innovation_initiatives}}
### Business Model Innovation
{{business_model_innovation}}
### Value Chain Opportunities
{{value_chain_opportunities}}
### Partnership and Ecosystem Plays
{{partnership_opportunities}}
---
## 🎲 STRATEGIC OPTIONS
### Option A: {{option_a_name}}
{{option_a_description}}
**Pros:** {{option_a_pros}}
**Cons:** {{option_a_cons}}
### Option B: {{option_b_name}}
{{option_b_description}}
**Pros:** {{option_b_pros}}
**Cons:** {{option_b_cons}}
### Option C: {{option_c_name}}
{{option_c_description}}
**Pros:** {{option_c_pros}}
**Cons:** {{option_c_cons}}
---
## 🏆 RECOMMENDED STRATEGY
### Strategic Direction
{{recommended_strategy}}
### Key Hypotheses to Validate
{{key_hypotheses}}
### Critical Success Factors
{{success_factors}}
---
## 📋 EXECUTION ROADMAP
### Phase 1: Immediate Impact
{{phase_1}}
### Phase 2: Foundation Building
{{phase_2}}
### Phase 3: Scale & Optimization
{{phase_3}}
---
## 📈 SUCCESS METRICS
### Leading Indicators
{{leading_indicators}}
### Lagging Indicators
{{lagging_indicators}}
### Decision Gates
{{decision_gates}}
---
## ⚠️ RISKS AND MITIGATION
### Key Risks
{{key_risks}}
### Mitigation Strategies
{{risk_mitigation}}
---
_Generated using BMAD Creative Intelligence Suite - Innovation Strategy Workflow_

View File

@@ -619,49 +619,24 @@ export default function GlossariesPage() {
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
{availableTemplates.map((template) => {
const Icon = TEMPLATE_ICONS[template.id] || BookText;
const isImported = importedTemplateIds.has(template.id);
const isProcessingThis = importingPresetId === template.id;
return (
<div
key={template.id}
className={cn(
'relative p-4 rounded-xl text-left border transition-all min-h-[110px] flex flex-col justify-between group',
isImported
? 'bg-emerald-500/5 dark:bg-emerald-500/5 border-emerald-500/20 dark:border-emerald-500/10 opacity-90'
: 'bg-brand-muted/40 dark:bg-white/5 border-black/5 dark:border-white/5 hover:border-brand-accent/20 hover:bg-brand-accent/[0.02]'
)}
className="relative p-4 rounded-xl text-left border transition-all min-h-[110px] flex flex-col justify-between group bg-brand-muted/40 dark:bg-white/5 border-black/5 dark:border-white/5 hover:border-brand-accent/20 hover:bg-brand-accent/[0.02]"
>
<div className="flex items-center justify-between gap-2 w-full">
<div className="p-1.5 bg-brand-accent/10 rounded-lg text-brand-accent group-hover:scale-115 transition-transform">
{isProcessingThis ? <Loader2 size={16} className="animate-spin" /> : <Icon className="size-4" />}
</div>
{isImported ? (
<div className="flex items-center gap-2">
<span className="flex items-center gap-1 text-[9px] font-bold uppercase tracking-wider text-emerald-600 dark:text-emerald-400 bg-emerald-500/10 px-2 py-0.5 rounded-full border border-emerald-500/20">
<CheckCircle2 size={9} /> {t('glossaries.presets.alreadyImported') || 'Importé'}
</span>
{(() => {
const matchingGlossary = glossaries.find((g) => g.template_id === template.id);
return matchingGlossary ? (
<Link
href={`/dashboard/glossaries/${matchingGlossary.id}`}
className="text-[9px] font-bold uppercase tracking-wider text-brand-accent hover:underline flex items-center gap-0.5"
>
Modifier
</Link>
) : null;
})()}
</div>
) : (
<button
disabled={isProcessing}
onClick={() => handleImportPreset(template.id, template.name)}
className="accent-pill !px-3 !py-1 !text-[9px] font-bold uppercase tracking-wider bg-brand-accent text-white hover:bg-brand-accent/90 rounded-md transition-colors cursor-pointer"
>
{t('glossaries.presets.importBtn') || 'Importer'}
</button>
)}
<button
disabled={isProcessing}
onClick={() => handleImportPreset(template.id, template.name)}
className="accent-pill !px-3 !py-1 !text-[9px] font-bold uppercase tracking-wider bg-brand-accent text-white hover:bg-brand-accent/90 rounded-md transition-colors cursor-pointer"
>
{t('glossaries.presets.importBtn') || 'Importer'}
</button>
</div>
<div className="mt-3">
<div className="flex justify-between items-baseline gap-2">