maestro-bundle 1.3.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/package.json +1 -1
  2. package/templates/bundle-ai-agents/skills/agent-orchestration/SKILL.md +107 -41
  3. package/templates/bundle-ai-agents/skills/agent-orchestration/references/graph-patterns.md +50 -0
  4. package/templates/bundle-ai-agents/skills/agent-orchestration/references/routing-strategies.md +47 -0
  5. package/templates/bundle-ai-agents/skills/api-design/SKILL.md +125 -16
  6. package/templates/bundle-ai-agents/skills/api-design/references/pydantic-patterns.md +72 -0
  7. package/templates/bundle-ai-agents/skills/api-design/references/rest-conventions.md +51 -0
  8. package/templates/bundle-ai-agents/skills/clean-architecture/SKILL.md +113 -21
  9. package/templates/bundle-ai-agents/skills/clean-architecture/references/dependency-injection.md +60 -0
  10. package/templates/bundle-ai-agents/skills/clean-architecture/references/layer-rules.md +56 -0
  11. package/templates/bundle-ai-agents/skills/context-engineering/SKILL.md +104 -36
  12. package/templates/bundle-ai-agents/skills/context-engineering/references/compression-techniques.md +76 -0
  13. package/templates/bundle-ai-agents/skills/context-engineering/references/context-budget-calculator.md +45 -0
  14. package/templates/bundle-ai-agents/skills/database-modeling/SKILL.md +146 -19
  15. package/templates/bundle-ai-agents/skills/database-modeling/references/index-strategies.md +48 -0
  16. package/templates/bundle-ai-agents/skills/database-modeling/references/naming-conventions.md +27 -0
  17. package/templates/bundle-ai-agents/skills/docker-containerization/SKILL.md +124 -15
  18. package/templates/bundle-ai-agents/skills/docker-containerization/references/compose-patterns.md +97 -0
  19. package/templates/bundle-ai-agents/skills/docker-containerization/references/dockerfile-checklist.md +37 -0
  20. package/templates/bundle-ai-agents/skills/eval-testing/SKILL.md +113 -25
  21. package/templates/bundle-ai-agents/skills/eval-testing/references/eval-types.md +52 -0
  22. package/templates/bundle-ai-agents/skills/eval-testing/references/golden-dataset-template.md +59 -0
  23. package/templates/bundle-ai-agents/skills/memory-management/SKILL.md +112 -28
  24. package/templates/bundle-ai-agents/skills/memory-management/references/memory-tiers.md +41 -0
  25. package/templates/bundle-ai-agents/skills/memory-management/references/namespace-conventions.md +41 -0
  26. package/templates/bundle-ai-agents/skills/prompt-engineering/SKILL.md +139 -47
  27. package/templates/bundle-ai-agents/skills/prompt-engineering/references/anti-patterns.md +59 -0
  28. package/templates/bundle-ai-agents/skills/prompt-engineering/references/prompt-templates.md +75 -0
  29. package/templates/bundle-ai-agents/skills/rag-pipeline/SKILL.md +104 -27
  30. package/templates/bundle-ai-agents/skills/rag-pipeline/references/chunking-strategies.md +27 -0
  31. package/templates/bundle-ai-agents/skills/rag-pipeline/references/embedding-models.md +31 -0
  32. package/templates/bundle-ai-agents/skills/rag-pipeline/references/rag-evaluation.md +39 -0
  33. package/templates/bundle-ai-agents/skills/testing-strategy/SKILL.md +127 -18
  34. package/templates/bundle-ai-agents/skills/testing-strategy/references/fixture-patterns.md +81 -0
  35. package/templates/bundle-ai-agents/skills/testing-strategy/references/naming-conventions.md +69 -0
  36. package/templates/bundle-base/skills/branch-strategy/SKILL.md +134 -21
  37. package/templates/bundle-base/skills/branch-strategy/references/branch-rules.md +40 -0
  38. package/templates/bundle-base/skills/code-review/SKILL.md +123 -38
  39. package/templates/bundle-base/skills/code-review/references/review-checklist.md +45 -0
  40. package/templates/bundle-base/skills/commit-pattern/SKILL.md +98 -39
  41. package/templates/bundle-base/skills/commit-pattern/references/conventional-commits.md +40 -0
  42. package/templates/bundle-data-pipeline/skills/data-preprocessing/SKILL.md +110 -19
  43. package/templates/bundle-data-pipeline/skills/data-preprocessing/references/pandas-cheatsheet.md +63 -0
  44. package/templates/bundle-data-pipeline/skills/data-preprocessing/references/pandera-schemas.md +44 -0
  45. package/templates/bundle-data-pipeline/skills/docker-containerization/SKILL.md +132 -16
  46. package/templates/bundle-data-pipeline/skills/docker-containerization/references/compose-patterns.md +82 -0
  47. package/templates/bundle-data-pipeline/skills/docker-containerization/references/dockerfile-best-practices.md +57 -0
  48. package/templates/bundle-data-pipeline/skills/feature-engineering/SKILL.md +143 -45
  49. package/templates/bundle-data-pipeline/skills/feature-engineering/references/encoding-guide.md +41 -0
  50. package/templates/bundle-data-pipeline/skills/feature-engineering/references/scaling-guide.md +38 -0
  51. package/templates/bundle-data-pipeline/skills/mlops-pipeline/SKILL.md +156 -37
  52. package/templates/bundle-data-pipeline/skills/mlops-pipeline/references/mlflow-commands.md +69 -0
  53. package/templates/bundle-data-pipeline/skills/model-training/SKILL.md +152 -33
  54. package/templates/bundle-data-pipeline/skills/model-training/references/evaluation-metrics.md +52 -0
  55. package/templates/bundle-data-pipeline/skills/model-training/references/model-selection-guide.md +41 -0
  56. package/templates/bundle-data-pipeline/skills/rag-pipeline/SKILL.md +127 -39
  57. package/templates/bundle-data-pipeline/skills/rag-pipeline/references/chunking-strategies.md +51 -0
  58. package/templates/bundle-data-pipeline/skills/rag-pipeline/references/embedding-models.md +49 -0
  59. package/templates/bundle-frontend-spa/skills/authentication/SKILL.md +196 -13
  60. package/templates/bundle-frontend-spa/skills/authentication/references/jwt-security.md +41 -0
  61. package/templates/bundle-frontend-spa/skills/component-design/SKILL.md +191 -41
  62. package/templates/bundle-frontend-spa/skills/component-design/references/accessibility-checklist.md +41 -0
  63. package/templates/bundle-frontend-spa/skills/component-design/references/tailwind-patterns.md +65 -0
  64. package/templates/bundle-frontend-spa/skills/e2e-testing/SKILL.md +241 -79
  65. package/templates/bundle-frontend-spa/skills/e2e-testing/references/playwright-selectors.md +66 -0
  66. package/templates/bundle-frontend-spa/skills/e2e-testing/references/test-patterns.md +82 -0
  67. package/templates/bundle-frontend-spa/skills/integration-api/SKILL.md +221 -31
  68. package/templates/bundle-frontend-spa/skills/integration-api/references/api-patterns.md +81 -0
  69. package/templates/bundle-frontend-spa/skills/react-patterns/SKILL.md +195 -70
  70. package/templates/bundle-frontend-spa/skills/react-patterns/references/component-checklist.md +22 -0
  71. package/templates/bundle-frontend-spa/skills/react-patterns/references/hook-patterns.md +63 -0
  72. package/templates/bundle-frontend-spa/skills/responsive-layout/SKILL.md +162 -22
  73. package/templates/bundle-frontend-spa/skills/responsive-layout/references/breakpoint-guide.md +63 -0
  74. package/templates/bundle-frontend-spa/skills/state-management/SKILL.md +158 -30
  75. package/templates/bundle-frontend-spa/skills/state-management/references/react-query-config.md +64 -0
  76. package/templates/bundle-frontend-spa/skills/state-management/references/state-patterns.md +78 -0
  77. package/templates/bundle-jhipster-microservices/skills/ci-cd-pipeline/SKILL.md +135 -45
  78. package/templates/bundle-jhipster-microservices/skills/ci-cd-pipeline/references/gitlab-ci-templates.md +93 -0
  79. package/templates/bundle-jhipster-microservices/skills/clean-architecture/SKILL.md +87 -21
  80. package/templates/bundle-jhipster-microservices/skills/clean-architecture/references/layer-rules.md +78 -0
  81. package/templates/bundle-jhipster-microservices/skills/ddd-tactical/SKILL.md +94 -25
  82. package/templates/bundle-jhipster-microservices/skills/ddd-tactical/references/ddd-patterns.md +48 -0
  83. package/templates/bundle-jhipster-microservices/skills/jhipster-angular/SKILL.md +63 -21
  84. package/templates/bundle-jhipster-microservices/skills/jhipster-angular/references/angular-microservices.md +40 -0
  85. package/templates/bundle-jhipster-microservices/skills/jhipster-angular/references/angular-structure.md +59 -0
  86. package/templates/bundle-jhipster-microservices/skills/jhipster-docker-k8s/SKILL.md +125 -91
  87. package/templates/bundle-jhipster-microservices/skills/jhipster-docker-k8s/references/docker-k8s-commands.md +68 -0
  88. package/templates/bundle-jhipster-microservices/skills/jhipster-entities/SKILL.md +72 -20
  89. package/templates/bundle-jhipster-microservices/skills/jhipster-entities/references/cross-service-entities.md +36 -0
  90. package/templates/bundle-jhipster-microservices/skills/jhipster-entities/references/jdl-types.md +56 -0
  91. package/templates/bundle-jhipster-microservices/skills/jhipster-gateway/SKILL.md +80 -8
  92. package/templates/bundle-jhipster-microservices/skills/jhipster-gateway/references/gateway-config.md +43 -0
  93. package/templates/bundle-jhipster-microservices/skills/jhipster-kafka/SKILL.md +115 -22
  94. package/templates/bundle-jhipster-microservices/skills/jhipster-kafka/references/kafka-events.md +39 -0
  95. package/templates/bundle-jhipster-microservices/skills/jhipster-registry/SKILL.md +92 -23
  96. package/templates/bundle-jhipster-microservices/skills/jhipster-registry/references/consul-config.md +61 -0
  97. package/templates/bundle-jhipster-microservices/skills/jhipster-service/SKILL.md +81 -18
  98. package/templates/bundle-jhipster-microservices/skills/jhipster-service/references/service-patterns.md +40 -0
  99. package/templates/bundle-jhipster-microservices/skills/testing-strategy/SKILL.md +101 -20
  100. package/templates/bundle-jhipster-microservices/skills/testing-strategy/references/test-naming.md +55 -0
  101. package/templates/bundle-jhipster-monorepo/skills/clean-architecture/SKILL.md +87 -21
  102. package/templates/bundle-jhipster-monorepo/skills/clean-architecture/references/layer-rules.md +78 -0
  103. package/templates/bundle-jhipster-monorepo/skills/ddd-tactical/SKILL.md +94 -25
  104. package/templates/bundle-jhipster-monorepo/skills/ddd-tactical/references/ddd-patterns.md +48 -0
  105. package/templates/bundle-jhipster-monorepo/skills/jhipster-angular/SKILL.md +99 -52
  106. package/templates/bundle-jhipster-monorepo/skills/jhipster-angular/references/angular-structure.md +59 -0
  107. package/templates/bundle-jhipster-monorepo/skills/jhipster-entities/SKILL.md +89 -36
  108. package/templates/bundle-jhipster-monorepo/skills/jhipster-entities/references/jdl-types.md +56 -0
  109. package/templates/bundle-jhipster-monorepo/skills/jhipster-liquibase/SKILL.md +123 -23
  110. package/templates/bundle-jhipster-monorepo/skills/jhipster-liquibase/references/liquibase-operations.md +95 -0
  111. package/templates/bundle-jhipster-monorepo/skills/jhipster-security/SKILL.md +106 -19
  112. package/templates/bundle-jhipster-monorepo/skills/jhipster-security/references/security-checklist.md +47 -0
  113. package/templates/bundle-jhipster-monorepo/skills/jhipster-spring/SKILL.md +84 -16
  114. package/templates/bundle-jhipster-monorepo/skills/jhipster-spring/references/spring-layers.md +41 -0
  115. package/templates/bundle-jhipster-monorepo/skills/testing-strategy/SKILL.md +101 -20
  116. package/templates/bundle-jhipster-monorepo/skills/testing-strategy/references/test-naming.md +55 -0
@@ -1,54 +1,96 @@
1
1
  ---
2
2
  name: rag-pipeline
3
- description: Construir pipeline RAG completo com ingestão, chunking, embedding, indexação e retrieval usando LangChain + pgvector. Use sempre que precisar implementar busca semântica, responder perguntas sobre documentos, ou criar um sistema de retrieval.
3
+ description: Build a complete RAG pipeline with document ingestion, chunking, embedding, vector indexing, and hybrid retrieval using LangChain and pgvector. Use when you need to implement semantic search, answer questions over documents, or create a retrieval-augmented generation system.
4
+ version: 1.0.0
5
+ author: Maestro
4
6
  ---
5
7
 
6
8
  # RAG Pipeline
7
9
 
8
- ## Pipeline completo
10
+ Build production-ready retrieval-augmented generation systems with LangChain, pgvector, and hybrid search.
9
11
 
10
- ```
11
- Documentos Loader Splitter Embeddings pgvector Retriever → Re-ranker → LLM
12
+ ## When to Use
13
+ - User needs to build a Q&A system over internal documents
14
+ - User wants to implement semantic search on a document corpus
15
+ - User needs to ingest and chunk documents for vector indexing
16
+ - User wants hybrid retrieval (semantic + keyword) with re-ranking
17
+ - User needs to set up a pgvector-backed vector store
18
+
19
+ ## Available Operations
20
+ 1. Ingest documents (Markdown, PDF, text) with LangChain loaders
21
+ 2. Split documents into chunks with RecursiveCharacterTextSplitter
22
+ 3. Generate embeddings and store in pgvector
23
+ 4. Build hybrid retrieval (semantic + BM25 keyword search)
24
+ 5. Add Cohere re-ranking for precision
25
+ 6. Create a query chain with LLM and source attribution
26
+
27
+ ## Multi-Step Workflow
28
+
29
+ ### Step 1: Install Dependencies
30
+ ```bash
31
+ pip install langchain langchain-openai langchain-community langchain-postgres langchain-cohere pgvector psycopg2-binary unstructured rank-bm25
12
32
  ```
13
33
 
14
- ## 1. Ingestão
34
+ Set required environment variables:
35
+ ```bash
36
+ export OPENAI_API_KEY="sk-..."
37
+ export COHERE_API_KEY="..."
38
+ export DATABASE_URL="postgresql://user:pass@localhost:5432/vectordb"
39
+ ```
15
40
 
41
+ ### Step 2: Ingest Documents
16
42
  ```python
17
43
  from langchain_community.document_loaders import DirectoryLoader, UnstructuredMarkdownLoader
18
- from langchain.text_splitter import RecursiveCharacterTextSplitter
19
44
 
20
- # Loader por tipo de documento
45
+ # Load all markdown files from a directory
21
46
  loader = DirectoryLoader(
22
47
  "./documents/",
23
48
  glob="**/*.md",
24
- loader_cls=UnstructuredMarkdownLoader
49
+ loader_cls=UnstructuredMarkdownLoader,
50
+ show_progress=True
25
51
  )
26
52
  docs = loader.load()
53
+ print(f"Loaded {len(docs)} documents")
54
+ ```
55
+
56
+ For PDF files:
57
+ ```python
58
+ from langchain_community.document_loaders import PyPDFLoader
59
+
60
+ loader = PyPDFLoader("documents/report.pdf")
61
+ docs = loader.load()
62
+ ```
63
+
64
+ ### Step 3: Split into Chunks
65
+ ```python
66
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
27
67
 
28
- # Splitter com separadores Markdown
29
68
  splitter = RecursiveCharacterTextSplitter(
30
69
  chunk_size=1000,
31
70
  chunk_overlap=200,
32
71
  separators=["\n## ", "\n### ", "\n\n", "\n", ". ", " "]
33
72
  )
34
73
  chunks = splitter.split_documents(docs)
74
+ print(f"Split into {len(chunks)} chunks")
35
75
  ```
36
76
 
37
- ## 2. Metadados obrigatórios
38
-
39
- Cada chunk deve ter:
77
+ ### Step 4: Enrich Metadata
40
78
  ```python
79
+ from datetime import datetime
80
+
41
81
  for chunk in chunks:
42
82
  chunk.metadata.update({
43
83
  "source": chunk.metadata.get("source", "unknown"),
44
- "doc_type": classify_document(chunk), # skill, agent_md, prd, code
45
- "language": detect_language(chunk),
46
- "created_at": datetime.now().isoformat(),
84
+ "doc_type": chunk.metadata.get("source", "").split(".")[-1],
85
+ "indexed_at": datetime.now().isoformat(),
86
+ "chunk_size": len(chunk.page_content),
47
87
  })
48
- ```
49
88
 
50
- ## 3. Embedding + Indexação
89
+ # Verify metadata
90
+ print(chunks[0].metadata)
91
+ ```
51
92
 
93
+ ### Step 5: Generate Embeddings and Store in pgvector
52
94
  ```python
53
95
  from langchain_openai import OpenAIEmbeddings
54
96
  from langchain_postgres import PGVector
@@ -61,29 +103,28 @@ vectorstore = PGVector(
61
103
  embedding_function=embeddings,
62
104
  )
63
105
  vectorstore.add_documents(chunks)
106
+ print(f"Indexed {len(chunks)} chunks in pgvector")
64
107
  ```
65
108
 
66
- ## 4. Retrieval Híbrido
67
-
109
+ ### Step 6: Build Hybrid Retriever (Semantic + BM25)
68
110
  ```python
69
111
  from langchain.retrievers import EnsembleRetriever
70
112
  from langchain_community.retrievers import BM25Retriever
71
113
 
72
- # Semântico
114
+ # Semantic retriever
73
115
  semantic_retriever = vectorstore.as_retriever(search_kwargs={"k": 20})
74
116
 
75
- # Keyword
117
+ # Keyword retriever (BM25)
76
118
  bm25_retriever = BM25Retriever.from_documents(chunks, k=20)
77
119
 
78
- # Ensemble com RRF
120
+ # Combine with Reciprocal Rank Fusion
79
121
  hybrid_retriever = EnsembleRetriever(
80
122
  retrievers=[semantic_retriever, bm25_retriever],
81
- weights=[0.6, 0.4]
123
+ weights=[0.6, 0.4] # favor semantic
82
124
  )
83
125
  ```
84
126
 
85
- ## 5. Re-ranking
86
-
127
+ ### Step 7: Add Re-Ranking
87
128
  ```python
88
129
  from langchain.retrievers import ContextualCompressionRetriever
89
130
  from langchain_cohere import CohereRerank
@@ -95,34 +136,81 @@ final_retriever = ContextualCompressionRetriever(
95
136
  )
96
137
  ```
97
138
 
98
- ## 6. Query Chain
99
-
139
+ ### Step 8: Build Query Chain
100
140
  ```python
141
+ from langchain_openai import ChatOpenAI
101
142
  from langchain_core.prompts import ChatPromptTemplate
102
143
  from langchain_core.output_parsers import StrOutputParser
144
+ from langchain_core.runnables import RunnablePassthrough
145
+
146
+ llm = ChatOpenAI(model="gpt-4o", temperature=0)
103
147
 
104
148
  prompt = ChatPromptTemplate.from_template("""
105
- Responda a pergunta baseado apenas no contexto fornecido.
106
- Se a resposta não estiver no contexto, diga "Não encontrei essa informação".
149
+ Answer the question based only on the provided context.
150
+ If the answer is not in the context, say "I could not find that information."
107
151
 
108
- Contexto: {context}
109
- Pergunta: {question}
152
+ Context: {context}
153
+ Question: {question}
110
154
  """)
111
155
 
156
+ def format_docs(docs):
157
+ return "\n\n".join(doc.page_content for doc in docs)
158
+
112
159
  chain = (
113
- {"context": final_retriever, "question": RunnablePassthrough()}
160
+ {"context": final_retriever | format_docs, "question": RunnablePassthrough()}
114
161
  | prompt
115
162
  | llm
116
163
  | StrOutputParser()
117
164
  )
118
165
 
119
- result = chain.invoke("Qual skill usar para criar componentes React?")
166
+ # Test the chain
167
+ result = chain.invoke("What is the recommended chunk size for markdown documents?")
168
+ print(result)
120
169
  ```
121
170
 
122
- ## Checklist de qualidade
171
+ ### Step 9: Verify Retrieval Quality
172
+ ```python
173
+ # Test retrieval with known questions
174
+ test_queries = [
175
+ "How do I set up authentication?",
176
+ "What database should I use?",
177
+ "How do I deploy with Docker?",
178
+ ]
179
+
180
+ for query in test_queries:
181
+ docs = final_retriever.invoke(query)
182
+ print(f"\nQuery: {query}")
183
+ print(f"Top result source: {docs[0].metadata.get('source', 'unknown')}")
184
+ print(f"Top result preview: {docs[0].page_content[:200]}...")
185
+ ```
123
186
 
124
- - [ ] Chunks testados com perguntas reais
125
- - [ ] Metadados completos em todos os chunks
126
- - [ ] Retrieval quality medido com golden dataset
127
- - [ ] Re-ranking ativo para refinar top-k
128
- - [ ] Fallback para quando retrieval não encontra nada
187
+ ## Resources
188
+ - `references/chunking-strategies.md` - Guide to chunk sizes, overlap, and separators
189
+ - `references/embedding-models.md` - Comparison of embedding model options
190
+
191
+ ## Examples
192
+ ### Example 1: Build Q&A Over Documentation
193
+ User asks: "Set up a RAG system to answer questions about our API docs"
194
+ Response approach:
195
+ 1. Load docs from the docs/ directory with DirectoryLoader
196
+ 2. Split with RecursiveCharacterTextSplitter (1000 chars, 200 overlap)
197
+ 3. Embed with OpenAI text-embedding-3-large and store in pgvector
198
+ 4. Build hybrid retriever with BM25 fallback
199
+ 5. Create query chain with GPT-4o
200
+ 6. Test with sample questions and verify source attribution
201
+
202
+ ### Example 2: Add Semantic Search to Existing App
203
+ User asks: "Add search to our knowledge base"
204
+ Response approach:
205
+ 1. Ingest existing knowledge base documents
206
+ 2. Index in pgvector with embeddings
207
+ 3. Expose a retriever endpoint that returns top-5 results
208
+ 4. Return results with source metadata and relevance scores
209
+
210
+ ## Notes
211
+ - Chunk size 800-1200 works well for most text; use 400-600 for code
212
+ - Always include chunk_overlap (15-20% of chunk_size) to preserve context across boundaries
213
+ - Use hybrid retrieval (semantic + BM25) for better recall than either alone
214
+ - Re-ranking is critical for precision -- always add it for production systems
215
+ - Test retrieval quality with a golden dataset of question-answer pairs before deploying
216
+ - Monitor retrieval metrics: precision@k, recall@k, MRR
@@ -0,0 +1,51 @@
1
+ # Chunking Strategies
2
+
3
+ ## Recommended Defaults
4
+
5
+ | Content Type | chunk_size | chunk_overlap | Separators |
6
+ |---|---|---|---|
7
+ | Prose / documentation | 1000 | 200 | `["\n## ", "\n### ", "\n\n", "\n", ". "]` |
8
+ | Code files | 500 | 50 | `["\nclass ", "\ndef ", "\n\n", "\n"]` |
9
+ | Legal / contracts | 1500 | 300 | `["\n\n", "\n", ". "]` |
10
+ | Chat logs / Q&A | 500 | 100 | `["\n\n", "\n"]` |
11
+
12
+ ## RecursiveCharacterTextSplitter
13
+ ```python
14
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
15
+
16
+ # For markdown docs
17
+ splitter = RecursiveCharacterTextSplitter(
18
+ chunk_size=1000,
19
+ chunk_overlap=200,
20
+ separators=["\n## ", "\n### ", "\n\n", "\n", ". ", " "]
21
+ )
22
+ ```
23
+
24
+ ## Code Splitting
25
+ ```python
26
+ from langchain.text_splitter import Language, RecursiveCharacterTextSplitter
27
+
28
+ python_splitter = RecursiveCharacterTextSplitter.from_language(
29
+ language=Language.PYTHON, chunk_size=500, chunk_overlap=50
30
+ )
31
+
32
+ ts_splitter = RecursiveCharacterTextSplitter.from_language(
33
+ language=Language.TS, chunk_size=500, chunk_overlap=50
34
+ )
35
+ ```
36
+
37
+ ## Validation
38
+ After chunking, verify:
39
+ 1. No chunks are empty or whitespace-only
40
+ 2. Average chunk size is close to target
41
+ 3. Metadata is preserved on all chunks
42
+ 4. Key information is not split across chunk boundaries (spot-check)
43
+
44
+ ```python
45
+ sizes = [len(c.page_content) for c in chunks]
46
+ print(f"Chunks: {len(chunks)}")
47
+ print(f"Avg size: {sum(sizes)/len(sizes):.0f}")
48
+ print(f"Min: {min(sizes)}, Max: {max(sizes)}")
49
+ empty = [c for c in chunks if len(c.page_content.strip()) == 0]
50
+ print(f"Empty chunks: {len(empty)}")
51
+ ```
@@ -0,0 +1,49 @@
1
+ # Embedding Models Comparison
2
+
3
+ ## OpenAI Models
4
+
5
+ | Model | Dimensions | Max Tokens | Best For |
6
+ |---|---|---|---|
7
+ | text-embedding-3-large | 3072 (or custom) | 8191 | Highest quality, production |
8
+ | text-embedding-3-small | 1536 | 8191 | Cost-effective, good quality |
9
+ | text-embedding-ada-002 | 1536 | 8191 | Legacy, still widely used |
10
+
11
+ ## Usage with LangChain
12
+ ```python
13
+ from langchain_openai import OpenAIEmbeddings
14
+
15
+ # Default (text-embedding-3-large with reduced dimensions)
16
+ embeddings = OpenAIEmbeddings(model="text-embedding-3-large", dimensions=1536)
17
+
18
+ # Full dimensions for maximum quality
19
+ embeddings = OpenAIEmbeddings(model="text-embedding-3-large", dimensions=3072)
20
+
21
+ # Cost-effective option
22
+ embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
23
+ ```
24
+
25
+ ## Open Source Alternatives
26
+ ```python
27
+ from langchain_community.embeddings import HuggingFaceEmbeddings
28
+
29
+ # All-MiniLM (fast, lightweight)
30
+ embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
31
+
32
+ # BGE (high quality, multilingual)
33
+ embeddings = HuggingFaceEmbeddings(model_name="BAAI/bge-large-en-v1.5")
34
+ ```
35
+
36
+ ## Dimensionality and pgvector
37
+ When creating the pgvector extension and table:
38
+ ```sql
39
+ CREATE EXTENSION IF NOT EXISTS vector;
40
+
41
+ -- Match dimensions to your embedding model
42
+ CREATE TABLE embeddings (
43
+ id SERIAL PRIMARY KEY,
44
+ content TEXT,
45
+ embedding vector(1536) -- adjust to match model dimensions
46
+ );
47
+
48
+ CREATE INDEX ON embeddings USING ivfflat (embedding vector_cosine_ops);
49
+ ```
@@ -1,17 +1,43 @@
1
1
  ---
2
2
  name: authentication
3
- description: Implementar autenticação JWT com login, refresh token e proteção de rotas no frontend e backend. Use quando precisar implementar login, auth, JWT, ou proteção de endpoints.
3
+ description: Implement JWT authentication with login, refresh tokens, route protection, and Axios interceptors for both frontend and backend. Use when you need to add login, JWT auth, protected routes, or token refresh to an application.
4
+ version: 1.0.0
5
+ author: Maestro
4
6
  ---
5
7
 
6
8
  # Authentication
7
9
 
8
- ## Backend JWT com FastAPI
10
+ Implement complete JWT authentication flow covering backend token generation, frontend auth state, Axios interceptors, and protected routes.
9
11
 
12
+ ## When to Use
13
+ - User needs to implement login/logout functionality
14
+ - User wants to protect routes requiring authentication
15
+ - User needs JWT token generation and validation (backend)
16
+ - User wants to add automatic token refresh
17
+ - User needs to set up Axios interceptors for auth headers
18
+
19
+ ## Available Operations
20
+ 1. Create JWT token generation and validation (FastAPI backend)
21
+ 2. Build login/logout flow with Zustand auth store
22
+ 3. Set up Axios interceptors for automatic Bearer token headers
23
+ 4. Implement protected route wrappers
24
+ 5. Add refresh token rotation
25
+
26
+ ## Multi-Step Workflow
27
+
28
+ ### Step 1: Install Backend Dependencies
29
+ ```bash
30
+ pip install fastapi python-jose[cryptography] passlib[bcrypt] python-multipart
31
+ ```
32
+
33
+ ### Step 2: Create JWT Token Utilities (Backend)
10
34
  ```python
35
+ # src/auth/jwt.py
36
+ import os
37
+ from datetime import datetime, timedelta
38
+ from jose import jwt, JWTError
11
39
  from fastapi import Depends, HTTPException, status
12
40
  from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
13
- from jose import jwt, JWTError
14
- from datetime import datetime, timedelta
15
41
 
16
42
  security = HTTPBearer()
17
43
  SECRET_KEY = os.environ["JWT_SECRET"]
@@ -23,7 +49,7 @@ def create_access_token(user_id: str) -> str:
23
49
  payload = {
24
50
  "sub": user_id,
25
51
  "exp": datetime.utcnow() + ACCESS_TOKEN_EXPIRE,
26
- "type": "access"
52
+ "type": "access",
27
53
  }
28
54
  return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)
29
55
 
@@ -31,11 +57,13 @@ def create_refresh_token(user_id: str) -> str:
31
57
  payload = {
32
58
  "sub": user_id,
33
59
  "exp": datetime.utcnow() + REFRESH_TOKEN_EXPIRE,
34
- "type": "refresh"
60
+ "type": "refresh",
35
61
  }
36
62
  return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)
37
63
 
38
- async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)) -> User:
64
+ async def get_current_user(
65
+ credentials: HTTPAuthorizationCredentials = Depends(security),
66
+ ) -> User:
39
67
  try:
40
68
  payload = jwt.decode(credentials.credentials, SECRET_KEY, algorithms=[ALGORITHM])
41
69
  if payload.get("type") != "access":
@@ -46,22 +74,68 @@ async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(s
46
74
  return user
47
75
  except JWTError:
48
76
  raise HTTPException(status_code=401, detail="Invalid token")
77
+ ```
78
+
79
+ ### Step 3: Create Auth Endpoints (Backend)
80
+ ```python
81
+ # src/auth/routes.py
82
+ from fastapi import APIRouter, HTTPException
83
+
84
+ router = APIRouter(prefix="/auth", tags=["auth"])
85
+
86
+ @router.post("/login")
87
+ async def login(data: LoginRequest):
88
+ user = await user_repo.find_by_email(data.email)
89
+ if not user or not verify_password(data.password, user.hashed_password):
90
+ raise HTTPException(status_code=401, detail="Invalid credentials")
91
+ return {
92
+ "access_token": create_access_token(str(user.id)),
93
+ "refresh_token": create_refresh_token(str(user.id)),
94
+ "user": UserResponse.from_entity(user),
95
+ }
96
+
97
+ @router.post("/refresh")
98
+ async def refresh(data: RefreshRequest):
99
+ try:
100
+ payload = jwt.decode(data.refresh_token, SECRET_KEY, algorithms=[ALGORITHM])
101
+ if payload.get("type") != "refresh":
102
+ raise HTTPException(status_code=401, detail="Invalid token type")
103
+ return {"access_token": create_access_token(payload["sub"])}
104
+ except JWTError:
105
+ raise HTTPException(status_code=401, detail="Invalid refresh token")
49
106
 
50
- # Endpoint protegido
51
107
  @router.get("/me")
52
108
  async def get_me(user: User = Depends(get_current_user)):
53
109
  return UserResponse.from_entity(user)
54
110
  ```
55
111
 
56
- ## Frontend — Auth Context
112
+ Test the backend:
113
+ ```bash
114
+ # Start the API server
115
+ uvicorn src.main:app --reload --port 8000
57
116
 
117
+ # Test login
118
+ curl -X POST http://localhost:8000/auth/login -H "Content-Type: application/json" -d '{"email": "admin@example.com", "password": "admin123"}'
119
+ ```
120
+
121
+ ### Step 4: Install Frontend Dependencies
122
+ ```bash
123
+ npm install axios zustand
124
+ ```
125
+
126
+ ### Step 5: Create Auth Store (Frontend)
58
127
  ```tsx
128
+ // src/stores/useAuthStore.ts
129
+ import { create } from 'zustand';
130
+ import { authApi } from '@/services/authApi';
131
+
59
132
  interface AuthState {
60
133
  token: string | null;
61
134
  user: User | null;
135
+ isAuthenticated: boolean;
62
136
  login: (email: string, password: string) => Promise<void>;
63
137
  logout: () => void;
64
- isAuthenticated: boolean;
138
+ setToken: (token: string) => void;
65
139
  }
66
140
 
67
141
  export const useAuthStore = create<AuthState>((set) => ({
@@ -70,21 +144,130 @@ export const useAuthStore = create<AuthState>((set) => ({
70
144
  isAuthenticated: !!localStorage.getItem('token'),
71
145
 
72
146
  login: async (email, password) => {
73
- const { access_token, user } = await authApi.login(email, password);
147
+ const { access_token, refresh_token, user } = await authApi.login(email, password);
74
148
  localStorage.setItem('token', access_token);
149
+ localStorage.setItem('refresh_token', refresh_token);
75
150
  set({ token: access_token, user, isAuthenticated: true });
76
151
  },
77
152
 
78
153
  logout: () => {
79
154
  localStorage.removeItem('token');
155
+ localStorage.removeItem('refresh_token');
80
156
  set({ token: null, user: null, isAuthenticated: false });
81
157
  },
158
+
159
+ setToken: (token) => {
160
+ localStorage.setItem('token', token);
161
+ set({ token });
162
+ },
82
163
  }));
164
+ ```
165
+
166
+ ### Step 6: Set Up Axios Interceptors
167
+ ```tsx
168
+ // src/lib/api.ts
169
+ import axios from 'axios';
170
+ import { useAuthStore } from '@/stores/useAuthStore';
83
171
 
84
- // Axios interceptor
172
+ export const api = axios.create({
173
+ baseURL: import.meta.env.VITE_API_URL || 'http://localhost:8000/api/v1',
174
+ timeout: 10000,
175
+ });
176
+
177
+ // Add auth header to every request
85
178
  api.interceptors.request.use((config) => {
86
179
  const token = localStorage.getItem('token');
87
- if (token) config.headers.Authorization = `Bearer ${token}`;
180
+ if (token) {
181
+ config.headers.Authorization = `Bearer ${token}`;
182
+ }
88
183
  return config;
89
184
  });
185
+
186
+ // Handle 401 responses: try refresh, then logout
187
+ api.interceptors.response.use(
188
+ (response) => response.data,
189
+ async (error) => {
190
+ if (error.response?.status === 401) {
191
+ const refreshToken = localStorage.getItem('refresh_token');
192
+ if (refreshToken && !error.config._retry) {
193
+ error.config._retry = true;
194
+ try {
195
+ const { access_token } = await authApi.refresh(refreshToken);
196
+ useAuthStore.getState().setToken(access_token);
197
+ error.config.headers.Authorization = `Bearer ${access_token}`;
198
+ return api(error.config);
199
+ } catch {
200
+ useAuthStore.getState().logout();
201
+ window.location.href = '/login';
202
+ }
203
+ } else {
204
+ useAuthStore.getState().logout();
205
+ window.location.href = '/login';
206
+ }
207
+ }
208
+ return Promise.reject(error.response?.data || error);
209
+ }
210
+ );
211
+ ```
212
+
213
+ ### Step 7: Create Protected Route Wrapper
214
+ ```tsx
215
+ // src/components/ProtectedRoute.tsx
216
+ import { Navigate } from 'react-router-dom';
217
+ import { useAuthStore } from '@/stores/useAuthStore';
218
+
219
+ export function ProtectedRoute({ children }: { children: React.ReactNode }) {
220
+ const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
221
+
222
+ if (!isAuthenticated) {
223
+ return <Navigate to="/login" replace />;
224
+ }
225
+
226
+ return <>{children}</>;
227
+ }
228
+
229
+ // Usage in router:
230
+ // <Route path="/dashboard" element={<ProtectedRoute><Dashboard /></ProtectedRoute>} />
90
231
  ```
232
+
233
+ ### Step 8: Verify the Auth Flow
234
+ ```bash
235
+ npm run dev
236
+ # 1. Navigate to /login
237
+ # 2. Enter credentials and submit
238
+ # 3. Verify redirect to /dashboard
239
+ # 4. Verify protected routes redirect to /login when not authenticated
240
+ # 5. Verify token is in localStorage
241
+ # 6. Verify API calls include Authorization header (check Network tab)
242
+ ```
243
+
244
+ ## Resources
245
+ - `references/jwt-security.md` - JWT security best practices and common vulnerabilities
246
+
247
+ ## Examples
248
+ ### Example 1: Add Login to an Existing App
249
+ User asks: "Add authentication to our React app with a login page"
250
+ Response approach:
251
+ 1. Create backend auth endpoints (login, refresh, me)
252
+ 2. Create useAuthStore with Zustand
253
+ 3. Set up Axios interceptors for token management
254
+ 4. Create LoginPage component with form
255
+ 5. Wrap routes in ProtectedRoute
256
+ 6. Test the full flow end-to-end
257
+
258
+ ### Example 2: Fix Token Expiry Issues
259
+ User asks: "Users keep getting logged out, how do I add token refresh?"
260
+ Response approach:
261
+ 1. Add refresh token endpoint to backend
262
+ 2. Store refresh token in localStorage alongside access token
263
+ 3. Add 401 interceptor that tries refresh before logging out
264
+ 4. Set retry flag to prevent infinite refresh loops
265
+ 5. Test by setting short access token expiry and verifying refresh works
266
+
267
+ ## Notes
268
+ - Never store tokens in cookies without httpOnly + secure + sameSite flags
269
+ - Set a reasonable access token expiry (1 hour) and longer refresh token (7 days)
270
+ - Always validate token type ("access" vs "refresh") server-side
271
+ - Use environment variables for JWT_SECRET, never hardcode
272
+ - Implement rate limiting on login endpoints to prevent brute force
273
+ - Clear all stored tokens on logout
@@ -0,0 +1,41 @@
1
+ # JWT Security Best Practices
2
+
3
+ ## Token Storage
4
+ | Method | Security | XSS Risk | CSRF Risk |
5
+ |---|---|---|---|
6
+ | localStorage | Low | High | None |
7
+ | httpOnly Cookie | High | None | Medium |
8
+ | In-memory (variable) | Highest | None | None |
9
+
10
+ Recommendation: Use httpOnly cookies for production, localStorage for development/SPAs.
11
+
12
+ ## Token Expiry
13
+ | Token Type | Recommended Expiry |
14
+ |---|---|
15
+ | Access Token | 15 min - 1 hour |
16
+ | Refresh Token | 7 - 30 days |
17
+
18
+ ## Security Checklist
19
+ - [ ] Use strong secret key (256+ bits): `openssl rand -hex 32`
20
+ - [ ] Set algorithm explicitly (HS256 or RS256), never "none"
21
+ - [ ] Validate token type (access vs refresh) on every endpoint
22
+ - [ ] Implement refresh token rotation (new refresh token on each use)
23
+ - [ ] Rate limit login endpoint (5 attempts per minute)
24
+ - [ ] Log failed login attempts
25
+ - [ ] Clear all tokens on logout (both client and server)
26
+ - [ ] Use HTTPS in production
27
+
28
+ ## Common Vulnerabilities
29
+ 1. **Algorithm confusion**: Always specify algorithm in `jwt.decode()`, never accept from token
30
+ 2. **Missing expiry check**: Always include `exp` claim
31
+ 3. **Token reuse after logout**: Maintain a blocklist or use short-lived tokens
32
+ 4. **Refresh without rotation**: Rotate refresh tokens to limit damage from stolen tokens
33
+
34
+ ## Generating a Secure Secret
35
+ ```bash
36
+ # Generate a 256-bit hex secret
37
+ openssl rand -hex 32
38
+
39
+ # Or with Python
40
+ python -c "import secrets; print(secrets.token_hex(32))"
41
+ ```