@relipa/ai-flow-kit 0.2.0 → 0.2.1

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 (38) hide show
  1. package/custom/rules/java/spring-boot-rules.md +209 -0
  2. package/custom/rules/javascript/nestjs-examples.md +41 -0
  3. package/custom/rules/javascript/nestjs-rules.md +42 -0
  4. package/custom/rules/javascript/nodejs-express-examples.md +35 -0
  5. package/custom/rules/javascript/nodejs-express-rules.md +49 -0
  6. package/custom/rules/javascript/reactjs-examples.md +380 -0
  7. package/custom/rules/javascript/reactjs-rules.md +173 -0
  8. package/custom/rules/php/php-examples.md +161 -0
  9. package/custom/rules/php/php-rules.md +127 -0
  10. package/custom/rules/python/python-django-examples.md +34 -0
  11. package/custom/rules/python/python-django-rules.md +48 -0
  12. package/custom/rules/python/python-examples.md +32 -0
  13. package/custom/rules/python/python-fastapi-examples.md +30 -0
  14. package/custom/rules/python/python-fastapi-rules.md +35 -0
  15. package/custom/rules/python/python-ml-examples.md +187 -0
  16. package/custom/rules/python/python-ml-rules.md +121 -0
  17. package/custom/rules/python/python-rules.md +58 -0
  18. package/custom/skills/ba-skills/skill-ba-qna-template-v1.md +4 -4
  19. package/custom/skills/ba-skills/skill-ba-qna-v1.md +6 -0
  20. package/custom/skills/create-system-requirement/SKILL.md +52 -16
  21. package/custom/skills/create-system-requirement/system-requirement-template-v1.md +128 -0
  22. package/custom/skills/impact-analysis/SKILL.md +106 -106
  23. package/custom/skills/report-customer/SKILL.md +99 -99
  24. package/custom/templates/nestjs.md +5 -72
  25. package/custom/templates/nodejs-express.md +5 -73
  26. package/custom/templates/php-plain.md +5 -261
  27. package/custom/templates/php.md +5 -261
  28. package/custom/templates/python-django.md +5 -71
  29. package/custom/templates/python-fastapi.md +5 -54
  30. package/custom/templates/python-ml.md +1 -269
  31. package/custom/templates/python.md +5 -79
  32. package/custom/templates/reactjs.md +5 -492
  33. package/custom/templates/shared/gate-workflow.md +1 -0
  34. package/custom/templates/shared/ml-gate-workflow.md +1 -0
  35. package/custom/templates/spring-boot.md +5 -224
  36. package/docs/common/CHANGELOG.md +20 -10
  37. package/package.json +1 -1
  38. package/scripts/init.js +143 -40
@@ -0,0 +1,127 @@
1
+ # PHP Rules
2
+
3
+ Full coding rules for this stack. Read this in full before writing or modifying any PHP code in this project — not just once, keep applying it to every edit in the session, not only the first.
4
+
5
+ ---
6
+
7
+ ## Architecture
8
+
9
+ Organise code in a layered structure. Avoid writing logic directly in view files.
10
+
11
+ ```
12
+ public/ # Web root — index.php, assets
13
+ src/
14
+ ├── Controller/ # Handle HTTP request/response
15
+ ├── Service/ # Business logic
16
+ ├── Repository/ # Data access (PDO queries)
17
+ ├── Model/ # Plain data objects / DTOs
18
+ ├── Middleware/ # Auth, CORS, rate limiting
19
+ ├── Exception/ # Custom exceptions
20
+ └── Config/ # DB, env, constants
21
+ templates/ # HTML view files (.php/.html)
22
+ ```
23
+
24
+ ---
25
+
26
+ ## Coding Rules
27
+
28
+ ### General
29
+
30
+ - Use **PHP 8.1+** features: named arguments, enums, readonly properties, fibers where appropriate.
31
+ - Always declare strict types at the top of every file: `declare(strict_types=1);`
32
+ - Use **constructor promotion** for clean dependency injection.
33
+ - Follow **PSR-12** coding style.
34
+ - Prefer `match` over long `switch` blocks.
35
+ - Never suppress errors with `@` — handle them properly.
36
+
37
+ ---
38
+
39
+ ### Security Rules (CRITICAL)
40
+
41
+ - **NEVER** interpolate user input into SQL — always use **PDO prepared statements**.
42
+ - **NEVER** output user input without escaping — always use `htmlspecialchars()`.
43
+ - Validate and sanitize ALL user input at the controller/entry boundary.
44
+ - Store passwords with `password_hash($pass, PASSWORD_BCRYPT)`, verify with `password_verify()`.
45
+ - Use `random_bytes()` / `bin2hex(random_bytes(32))` for tokens — never `rand()` or `md5()`.
46
+ - Always validate uploaded file MIME types server-side — never trust the browser.
47
+
48
+ ---
49
+
50
+ ### Database / Repository Rules
51
+
52
+ - All DB access goes through Repository classes — never call PDO from controllers or services.
53
+ - Use PDO with `PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION`.
54
+ - Wrap multi-step writes in transactions.
55
+ - Return plain arrays or typed DTO objects from repositories — never raw `PDOStatement`.
56
+
57
+ ---
58
+
59
+ ### Controller Rules
60
+
61
+ - Controllers handle HTTP only: parse input, call service, output response.
62
+ - Never put business logic or direct DB calls in controllers.
63
+ - Validate input before passing to the service layer.
64
+ - For JSON APIs: always set `Content-Type: application/json` and return consistent response shape.
65
+
66
+ ---
67
+
68
+ ### Error Handling
69
+
70
+ - Define custom exception classes (`NotFoundException`, `ValidationException`, etc.).
71
+ - Register a global exception handler via `set_exception_handler()`.
72
+ - Never expose stack traces or internal paths to the client.
73
+ - Log errors to a file/syslog with a timestamp and context.
74
+
75
+ ---
76
+
77
+ ### Autoloading
78
+
79
+ - Use **Composer autoload** (PSR-4) — no manual `require` chains.
80
+ - `composer.json` minimum:
81
+
82
+ ```json
83
+ {
84
+ "autoload": {
85
+ "psr-4": {
86
+ "App\\": "src/"
87
+ }
88
+ }
89
+ }
90
+ ```
91
+
92
+ ---
93
+
94
+ ## Naming Conventions
95
+
96
+ | Element | Convention | Example |
97
+ |---------|-----------|---------|
98
+ | Class | PascalCase | `UserService`, `OrderRepository` |
99
+ | Method | camelCase | `findById`, `createOrder` |
100
+ | Variable | camelCase | `$userId`, `$orderList` |
101
+ | Constant | UPPER_SNAKE_CASE | `MAX_LOGIN_ATTEMPTS` |
102
+ | DB table | snake_case | `user_orders` |
103
+ | DB column | snake_case | `created_at` |
104
+ | File | Matches class name | `UserService.php` |
105
+
106
+ ---
107
+
108
+ ## Testing Rules
109
+
110
+ - Use **PHPUnit** for unit and integration tests.
111
+ - Test class mirrors source path: `tests/Service/UserServiceTest.php`.
112
+ - Mock dependencies with `$this->createMock()` or a stub.
113
+ - Cover: happy path, validation errors, not-found cases.
114
+
115
+ ---
116
+
117
+ ## Anti-Patterns to Avoid
118
+
119
+ - ❌ Raw SQL in controllers or views
120
+ - ❌ User input directly in SQL / HTML output
121
+ - ❌ Global `$_GET` / `$_POST` access outside the controller boundary
122
+ - ❌ `die()` / `exit()` for error handling — use exceptions
123
+ - ❌ Storing plain-text passwords
124
+ - ❌ `include`/`require` inside business logic — use autoloading
125
+ - ❌ Logic-heavy view files (`.php` templates should only render)
126
+
127
+ When explaining changes, refer to the [PHP Manual](https://www.php.net/manual) and [PSR standards](https://www.php-fig.org/psr/).
@@ -0,0 +1,34 @@
1
+ # Django Code Examples
2
+
3
+ Reference examples for each rule area. Read the relevant section when generating code for that area.
4
+
5
+ ---
6
+
7
+ ## Django Rules
8
+
9
+ ```python
10
+ # ✅ Good: Logic in service
11
+ class UserService:
12
+ @staticmethod
13
+ def create_user(validated_data):
14
+ return User.objects.create_user(**validated_data)
15
+
16
+ # View calls service
17
+ class UserCreateView(CreateAPIView):
18
+ serializer_class = UserSerializer
19
+ def perform_create(self, serializer):
20
+ UserService.create_user(serializer.validated_data)
21
+ ```
22
+
23
+ ---
24
+
25
+ ## Testing
26
+
27
+ ```python
28
+ class UserApiTest(APITestCase):
29
+ def test_create_user(self):
30
+ url = reverse('user-list')
31
+ data = {'email': 'test@example.com', 'password': 'password123'}
32
+ response = self.client.post(url, data, format='json')
33
+ assert response.status_code == status.HTTP_201_CREATED
34
+ ```
@@ -0,0 +1,48 @@
1
+ # Django Rules
2
+
3
+ Full coding rules for this stack. Read this in full before writing or modifying any Django code in this project — not just once, keep applying it to every edit in the session, not only the first.
4
+
5
+ ---
6
+
7
+ ## Project Structure
8
+
9
+ Follow the **MVT (Model-View-Template)** pattern or **MTV** for REST APIs with Django REST Framework (DRF):
10
+
11
+ ```
12
+ project/
13
+ ├── core/ # Project settings, wsgi, asgi
14
+ └── apps/
15
+ └── [app-name]/
16
+ ├── models.py # Database models
17
+ ├── views.py # API views or Template views
18
+ ├── serializers.py # DRF serializers
19
+ ├── services.py # Business logic (prefer over logic in views/models)
20
+ ├── urls.py # App-specific routing
21
+ ├── tests.py # Tests
22
+ └── admin.py # Admin configuration
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Django Rules
28
+
29
+ - Use **Class-Based Views (CBVs)** for standard REST operations.
30
+ - Prefer **Django REST Framework (DRF)** for building APIs.
31
+ - Keep business logic in **Services** (or Action classes) rather than in Models or Views to keep them thin.
32
+ - Always use **Serializers** for data validation and transformation.
33
+ - Leverage Django's built-in **Authentication** and **Permission** systems.
34
+
35
+ ---
36
+
37
+ ## Security Rules
38
+
39
+ - Use `environ` for sensitive settings (DEBUG, SECRET_KEY).
40
+ - Never use `DEBUG = True` in production.
41
+ - Always validate input through Forms or Serializers.
42
+
43
+ ---
44
+
45
+ ## Testing Rules
46
+
47
+ - Use **Django Test Case** or **Pytest-Django**.
48
+ - Use `factories` (FactoryBoy) for object creation in tests.
@@ -0,0 +1,32 @@
1
+ # Python Code Examples
2
+
3
+ Reference examples for each rule area. Read the relevant section when generating code for that area.
4
+
5
+ ---
6
+
7
+ ## Python Rules
8
+
9
+ ```python
10
+ # ✅ Good
11
+ from dataclasses import dataclass
12
+
13
+ @dataclass
14
+ class UserRequest:
15
+ email: str
16
+ full_name: str
17
+
18
+ def create_user(request: UserRequest) -> UserResponse:
19
+ if not request.email:
20
+ raise ValueError("email is required")
21
+ ...
22
+ ```
23
+
24
+ ---
25
+
26
+ ## Testing
27
+
28
+ ```python
29
+ def test_create_user_raises_when_email_is_empty():
30
+ with pytest.raises(ValueError, match="email is required"):
31
+ create_user(UserRequest(email="", full_name="Test"))
32
+ ```
@@ -0,0 +1,30 @@
1
+ # FastAPI Code Examples
2
+
3
+ Reference examples for each rule area. Read the relevant section when generating code for that area.
4
+
5
+ ---
6
+
7
+ ## FastAPI Rules
8
+
9
+ ```python
10
+ # ✅ Good: Schema and Dependency Injection
11
+ @router.post("/", response_model=UserRead)
12
+ async def create_user(
13
+ *,
14
+ db: Session = Depends(get_db),
15
+ user_in: UserCreate
16
+ ):
17
+ user = await crud.user.create(db, obj_in=user_in)
18
+ return user
19
+ ```
20
+
21
+ ---
22
+
23
+ ## Testing
24
+
25
+ ```python
26
+ @pytest.mark.asyncio
27
+ async def test_create_user(client: AsyncClient):
28
+ response = await client.post("/users/", json={"email": "test@example.com", "password": "password"})
29
+ assert response.status_code == 201
30
+ ```
@@ -0,0 +1,35 @@
1
+ # FastAPI Rules
2
+
3
+ Full coding rules for this stack. Read this in full before writing or modifying any FastAPI code in this project — not just once, keep applying it to every edit in the session, not only the first.
4
+
5
+ ---
6
+
7
+ ## Project Structure
8
+
9
+ ```
10
+ app/
11
+ ├── main.py # App entry point & routing configuration
12
+ ├── api/ # API routes (divided by feature)
13
+ ├── core/ # App-wide settings, security, and utils
14
+ ├── crud/ # Database operations (Create, Read, Update, Delete)
15
+ ├── models/ # Database models (SQLAlchemy/SQLModel)
16
+ ├── schemas/ # Pydantic schemas (Request/Response models)
17
+ ├── db/ # Database session & engine configuration
18
+ └── tests/ # Pytest suite
19
+ ```
20
+
21
+ ---
22
+
23
+ ## FastAPI Rules
24
+
25
+ - Use **Async/Await** for all I/O bound operations (database calls, external APIs).
26
+ - Always use **Pydantic** schemas for request body validation and response serialization.
27
+ - Use **Dependency Injection** (via `Depends`) for database sessions, authentication, and reusable logic.
28
+ - Document every endpoint using FastAPI's built-in OpenAPI support (Docstrings and Pydantic field descriptions).
29
+
30
+ ---
31
+
32
+ ## Testing Rules
33
+
34
+ - Use **Pytest** and `httpx` (AsyncClient) for integration testing.
35
+ - Test both success and failure cases for each endpoint.
@@ -0,0 +1,187 @@
1
+ # Python ML/AI Code Examples
2
+
3
+ Reference examples for each rule area. Read the relevant section when generating code for that area.
4
+
5
+ ---
6
+
7
+ ## Reproducibility
8
+
9
+ ```python
10
+ # ✅ Good — set all seeds at entrypoint
11
+ import random, numpy as np, torch
12
+
13
+ def set_seed(seed: int) -> None:
14
+ random.seed(seed)
15
+ np.random.seed(seed)
16
+ torch.manual_seed(seed)
17
+ torch.use_deterministic_algorithms(True)
18
+ ```
19
+
20
+ ---
21
+
22
+ ## Config Management
23
+
24
+ ```python
25
+ # ✅ Good — load config from file
26
+ from dataclasses import dataclass
27
+ import yaml
28
+
29
+ @dataclass
30
+ class TrainConfig:
31
+ lr: float
32
+ max_epochs: int
33
+ batch_size: int
34
+ seed: int
35
+
36
+ def load_config(path: str) -> TrainConfig:
37
+ with open(path) as f:
38
+ return TrainConfig(**yaml.safe_load(f))
39
+
40
+ # ❌ Bad — hyperparameters hardcoded in training script
41
+ lr = 0.001
42
+ epochs = 50
43
+ ```
44
+
45
+ ---
46
+
47
+ ## Leakage Prevention
48
+
49
+ ```python
50
+ # ✅ Good — pipeline inside CV; transforms fit on train fold only
51
+ from sklearn.pipeline import Pipeline
52
+ from sklearn.preprocessing import StandardScaler
53
+ from sklearn.linear_model import LogisticRegression
54
+ from sklearn.model_selection import StratifiedKFold, cross_val_score
55
+
56
+ pipe = Pipeline([
57
+ ("scaler", StandardScaler()),
58
+ ("clf", LogisticRegression()),
59
+ ])
60
+ cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
61
+ scores = cross_val_score(pipe, X_train, y_train, cv=cv, scoring="roc_auc")
62
+
63
+ # ❌ Bad — scaler fit on full data before split (leakage)
64
+ scaler = StandardScaler().fit(X)
65
+ X_scaled = scaler.transform(X)
66
+ X_train, X_test = train_test_split(X_scaled, ...)
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Framework Idioms
72
+
73
+ ### scikit-learn
74
+
75
+ ```python
76
+ from sklearn.compose import ColumnTransformer
77
+ from sklearn.preprocessing import StandardScaler, OneHotEncoder
78
+ from sklearn.pipeline import Pipeline
79
+
80
+ preprocessor = ColumnTransformer([
81
+ ("num", StandardScaler(), num_cols),
82
+ ("cat", OneHotEncoder(handle_unknown="ignore"), cat_cols),
83
+ ])
84
+ pipe = Pipeline([("prep", preprocessor), ("model", clf)])
85
+ ```
86
+
87
+ ### PyTorch
88
+
89
+ ```python
90
+ import torch
91
+ from torch.utils.data import DataLoader
92
+
93
+ def seed_worker(worker_id: int) -> None:
94
+ import random, numpy as np
95
+ worker_seed = torch.initial_seed() % (2**32)
96
+ random.seed(worker_seed)
97
+ np.random.seed(worker_seed)
98
+
99
+ g = torch.Generator()
100
+ g.manual_seed(42)
101
+ loader = DataLoader(dataset, batch_size=32, worker_init_fn=seed_worker, generator=g)
102
+
103
+ # Training loop
104
+ model.train()
105
+ for batch in train_loader:
106
+ ...
107
+
108
+ # Validation loop
109
+ model.eval()
110
+ with torch.no_grad():
111
+ for batch in val_loader:
112
+ ...
113
+ ```
114
+
115
+ ### TensorFlow / Keras
116
+
117
+ ```python
118
+ import tensorflow as tf
119
+
120
+ tf.random.set_seed(42)
121
+
122
+ callbacks = [
123
+ tf.keras.callbacks.ModelCheckpoint(
124
+ filepath="models/best.keras",
125
+ monitor="val_loss",
126
+ save_best_only=True,
127
+ ),
128
+ tf.keras.callbacks.EarlyStopping(
129
+ monitor="val_loss",
130
+ patience=5,
131
+ restore_best_weights=True,
132
+ ),
133
+ ]
134
+ model.fit(X_train, y_train, validation_data=(X_val, y_val), callbacks=callbacks)
135
+ ```
136
+
137
+ ### HuggingFace (LLM fine-tuning)
138
+
139
+ ```python
140
+ from transformers import Trainer, TrainingArguments
141
+
142
+ args = TrainingArguments(
143
+ output_dir="models/ft-run",
144
+ num_train_epochs=3,
145
+ learning_rate=2e-5,
146
+ warmup_ratio=0.1,
147
+ seed=42,
148
+ report_to="mlflow",
149
+ )
150
+ trainer = Trainer(model=model, args=args, train_dataset=train_ds, eval_dataset=val_ds)
151
+ trainer.train()
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Experiment Tracking
157
+
158
+ ```python
159
+ import mlflow
160
+
161
+ mlflow.set_experiment("my-project")
162
+ with mlflow.start_run(run_name="ML-42_lgbm-tfidf_20241115-1"):
163
+ mlflow.log_params({"lr": cfg.lr, "seed": cfg.seed, "data_version": "v1.2"})
164
+ mlflow.log_metric("val_roc_auc", val_score)
165
+ mlflow.sklearn.log_model(pipe, artifact_path="model")
166
+ ```
167
+
168
+ ---
169
+
170
+ ## Testing
171
+
172
+ ```python
173
+ import pytest
174
+ import numpy as np
175
+ from src.eval.metrics import binary_roc_auc
176
+ from src.data.splits import make_temporal_split
177
+
178
+ def test_roc_auc_perfect_classifier():
179
+ y_true = np.array([0, 0, 1, 1])
180
+ y_score = np.array([0.1, 0.2, 0.8, 0.9])
181
+ assert binary_roc_auc(y_true, y_score) == pytest.approx(1.0)
182
+
183
+ def test_temporal_split_no_leakage():
184
+ train_ids, test_ids = make_temporal_split(df, date_col="event_date", test_months=3)
185
+ overlap = set(train_ids) & set(test_ids)
186
+ assert len(overlap) == 0, f"Leakage: {len(overlap)} overlapping IDs"
187
+ ```
@@ -0,0 +1,121 @@
1
+ # Python ML/AI Rules
2
+
3
+ Full coding rules for this stack — covers scikit-learn, PyTorch, TensorFlow/Keras, and experiment tracking (MLflow / wandb / DVC). Read this in full before writing or modifying any ML/AI code in this project — not just once, keep applying it to every edit in the session, not only the first.
4
+
5
+ ---
6
+
7
+ ## Project Structure
8
+
9
+ ```
10
+ project/
11
+ ├── data/ # raw/, interim/, processed/ (git-ignored, DVC-tracked)
12
+ ├── notebooks/ # EDA only — not productionized code
13
+ ├── src/
14
+ │ ├── data/ # loading + splitting
15
+ │ ├── features/ # feature engineering (fit on train only)
16
+ │ ├── models/ # model definitions + training entrypoints
17
+ │ └── eval/ # metric + evaluation harness
18
+ ├── configs/ # YAML/Hydra hyperparameter configs
19
+ ├── experiments/ # tracked run outputs / logs
20
+ ├── models/ # saved artifacts (DVC/registry-tracked)
21
+ ├── requirements.txt # pinned
22
+ └── pyproject.toml
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Reproducibility Rules
28
+
29
+ - Set **all seeds** before any randomness: `random.seed(n)`, `numpy.random.seed(n)`, and the framework seed.
30
+ - Enable deterministic flags where feasible; document any performance trade-off.
31
+ - **Pin the environment:** `requirements.txt` or a lockfile committed alongside every artifact.
32
+ - Log the seed, config, and git commit SHA with every tracked run.
33
+
34
+ ---
35
+
36
+ ## Config Management
37
+
38
+ - Hyperparameters live in YAML / Hydra / argparse configs — **never hardcoded**.
39
+ - The config file is saved alongside every model artifact.
40
+
41
+ ---
42
+
43
+ ## Leakage Prevention
44
+
45
+ - **Split before fit** — perform the split BEFORE fitting any transformer, scaler, or encoder.
46
+ - **Fit transforms on train fold only** — all preprocessing lives inside a `Pipeline` fit only on training data.
47
+ - **Time-aware splits** — for temporal data, use `TimeSeriesSplit`; never shuffle time-indexed data.
48
+
49
+ ---
50
+
51
+ ## Framework Idioms
52
+
53
+ ### scikit-learn
54
+
55
+ - Use `Pipeline` + `ColumnTransformer` for all preprocessing — never transform outside a pipeline.
56
+ - Use `set_output(transform="pandas")` (sklearn ≥ 1.2) to preserve feature names.
57
+
58
+ ### PyTorch
59
+
60
+ - Seed the `DataLoader` worker init function for full reproducibility.
61
+ - Always switch between `model.train()` and `model.eval()` modes; use `torch.no_grad()` for validation.
62
+
63
+ ### TensorFlow / Keras
64
+
65
+ - Use callbacks for checkpointing (save best by validation metric) and early stopping.
66
+ - Set `tf.random.set_seed` at startup.
67
+
68
+ ### HuggingFace (LLM fine-tuning)
69
+
70
+ - Use a freeze/unfreeze schedule; start with a small learning rate and add warmup.
71
+ - Log the base model name, adapter config, and dataset version alongside the run.
72
+
73
+ ---
74
+
75
+ ## Experiment Tracking
76
+
77
+ - Log params, metrics per epoch/fold, seed, data version, and git commit to MLflow or wandb.
78
+ - Name each run per the scheme in `custom/rules/ml-conventions.md`: `[ticket-id]_[approach]_[yyyymmdd-n]`.
79
+ - Version datasets with DVC; store the DVC data hash in the run metadata.
80
+
81
+ ---
82
+
83
+ ## Notebook Hygiene
84
+
85
+ - `notebooks/` is for EDA and exploration only — not production code.
86
+ - Productionized logic (features, models, eval) migrates to `src/` as importable modules.
87
+ - Notebooks must not import from each other; shared utilities go to `src/`.
88
+ - Clear outputs before committing notebooks (or use `nbstripout`).
89
+
90
+ ---
91
+
92
+ ## Testing Rules
93
+
94
+ - Use **Pytest** for all `src/` utilities.
95
+ - Test the **metric harness** directly: assert known inputs produce the expected metric value.
96
+ - Test **data-split functions** for leakage: verify no sample ID appears in both train and test sets.
97
+ - Test feature-engineering functions independently with synthetic data.
98
+
99
+ ---
100
+
101
+ ## Naming Conventions
102
+
103
+ | Element | Convention | Example |
104
+ |---------|-----------|---------|
105
+ | Module/package | snake_case | `feature_engineering.py` |
106
+ | Class | PascalCase | `TemporalSplit`, `TrainConfig` |
107
+ | Function/variable | snake_case | `train_model`, `val_score` |
108
+ | Constant | UPPER_SNAKE_CASE | `DEFAULT_SEED`, `MAX_EPOCHS` |
109
+ | Experiment run | `[ticket-id]_[approach]_[yyyymmdd-n]` | `ML-42_lgbm-tfidf_20241115-1` |
110
+
111
+ ---
112
+
113
+ ## Common Anti-Patterns to Avoid
114
+
115
+ - ❌ Fitting scalers/encoders on the full dataset before splitting — always fit inside a `Pipeline` on the train fold only
116
+ - ❌ Hardcoded hyperparameters — use configs
117
+ - ❌ No seeds — always set `random`, `numpy`, and framework seeds
118
+ - ❌ Evaluating on validation data used for tuning — keep a held-out test set for final Gate 4 reporting
119
+ - ❌ Production logic in notebooks — migrate to `src/`
120
+ - ❌ Committing data files or model binaries to git — track with DVC or a registry
121
+ - ❌ Single aggregate metric without error analysis — always inspect failure cases and slices
@@ -0,0 +1,58 @@
1
+ # Python Rules
2
+
3
+ Full coding rules for this stack. Read this in full before writing or modifying any Python code in this project — not just once, keep applying it to every edit in the session, not only the first.
4
+
5
+ ---
6
+
7
+ ## Project Structure
8
+
9
+ ```
10
+ project/
11
+ ├── main.py # Entry point
12
+ ├── src/
13
+ │ ├── service/ # Business logic
14
+ │ ├── repository/ # Data access layer
15
+ │ ├── model/ # Data classes / domain models
16
+ │ └── util/ # Pure helper functions
17
+ ├── tests/ # Pytest suite
18
+ ├── requirements.txt
19
+ └── pyproject.toml
20
+ ```
21
+
22
+ ---
23
+
24
+ ## Python Rules
25
+
26
+ - Use **type hints** on all function signatures and return types.
27
+ - Follow **PEP 8** and keep functions small and single-purpose.
28
+ - Use **dataclasses** or **NamedTuple** for value objects; avoid plain dicts for structured data.
29
+ - Prefer **pathlib** over `os.path`; prefer `with` statements for file/resource handling.
30
+ - Raise specific exceptions — never `raise Exception("message")`.
31
+
32
+ ---
33
+
34
+ ## Testing Rules
35
+
36
+ - Use **Pytest** for all tests.
37
+ - Name test functions `test_<what>_<expected_outcome>`.
38
+ - Use `pytest.raises` to assert exceptions.
39
+
40
+ ---
41
+
42
+ ## Naming Conventions
43
+
44
+ | Element | Convention | Example |
45
+ |---------|-----------|---------|
46
+ | Module/package | snake_case | `user_service.py` |
47
+ | Class | PascalCase | `UserService` |
48
+ | Function/variable | snake_case | `find_by_id`, `user_id` |
49
+ | Constant | UPPER_SNAKE_CASE | `MAX_RETRY` |
50
+
51
+ ---
52
+
53
+ ## Common Anti-Patterns to Avoid
54
+
55
+ - ❌ Bare `except:` — always catch a specific exception type
56
+ - ❌ Mutable default arguments (`def f(x=[])`) — use `None` sentinel instead
57
+ - ❌ Global state — pass dependencies explicitly
58
+ - ❌ Returning `None` implicitly on error paths — raise or return a typed result
@@ -10,10 +10,10 @@ Mẫu tài liệu dùng để trình bày danh sách câu hỏi Q&A và theo dõ
10
10
 
11
11
  ## Danh sách câu hỏi Q&A
12
12
 
13
- | ID | Chức năng / Màn hình | Nội dung yêu cầu hiện tại | Câu hỏi / Điểm chưa rõ | Đề xuất giải pháp (Options) | Mức độ ảnh hưởng | Câu trả lời của Khách hàng | Trạng thái |
14
- | :-: | :--- | :--- | :--- | :--- | :-: | :--- | :-: |
15
- | **QA-01** | *Đăng nhập* | *Có text link đổi mật khẩu* | *Text link này sẽ dẫn sang URL cụ thể nào? Hệ thống tự sinh OTP gửi mail hay chuyển sang màn nhập email?* | *- Option A: Chuyển sang URL `/forgot-password` để nhập Email nhận link reset.<br>- Option B: Hiển thị popup nhập SĐT nhận OTP.* | 🔴 Blocking | *Khách hàng phản hồi: Chọn Option A, link URL là `/forgot-password`* | **Confirmed** |
16
- | **QA-02** | *Đăng nhập* | *Thông báo lỗi khi sai mật khẩu* | *Câu chữ thông báo lỗi cụ thể là gì?* | *- Option A: "Email hoặc mật khẩu không đúng."<br>- Option B: Ý kiến khác...* | 🟡 Non-blocking | *Chưa trả lời — khách hàng cần hỏi lại team Marketing* | **Open** |
13
+ | ID | Chức năng / Màn hình | Nội dung yêu cầu hiện tại | Câu hỏi / Điểm chưa rõ | Đề xuất giải pháp (Options) | Mức độ ảnh hưởng | Câu trả lời của Khách hàng | Người trả lời | Ngày trả lời | Nguồn | Trạng thái |
14
+ | :-: | :--- | :--- | :--- | :--- | :-: | :--- | :--- | :-: | :--- | :-: |
15
+ | **QA-01** | *Đăng nhập* | *Có text link đổi mật khẩu* | *Text link này sẽ dẫn sang URL cụ thể nào? Hệ thống tự sinh OTP gửi mail hay chuyển sang màn nhập email?* | *- Option A: Chuyển sang URL `/forgot-password` để nhập Email nhận link reset.<br>- Option B: Hiển thị popup nhập SĐT nhận OTP.* | 🔴 Blocking | *Khách hàng phản hồi: Chọn Option A, link URL là `/forgot-password`* | *Nguyễn Văn A (PO)* | *12/07/2026* | *Khách hàng* | **Confirmed** |
16
+ | **QA-02** | *Đăng nhập* | *Thông báo lỗi khi sai mật khẩu* | *Câu chữ thông báo lỗi cụ thể là gì?* | *- Option A: "Email hoặc mật khẩu không đúng."<br>- Option B: Ý kiến khác...* | 🟡 Non-blocking | *Chưa trả lời — khách hàng cần hỏi lại team Marketing* | *—* | *—* | *—* | **Open** |
17
17
 
18
18
  ---
19
19
  ## Lịch sử cập nhật tài liệu