feat(mcp): migration 0007 kind + init schema jetons au démarrage (scope B #111)
This commit is contained in:
+8
-4
@@ -5,6 +5,14 @@ from src.api import routes
|
|||||||
|
|
||||||
def init_api(server) -> None:
|
def init_api(server) -> None:
|
||||||
"""Enregistre le blueprint d'API privée sur le serveur Flask."""
|
"""Enregistre le blueprint d'API privée sur le serveur Flask."""
|
||||||
|
import os
|
||||||
|
|
||||||
|
from src.api import tokens_db, tracking
|
||||||
|
|
||||||
|
# Garantit que api_tokens existe avant que apply_pending (init_subscriptions,
|
||||||
|
# plus tard) ne tente l'ALTER de la migration 0007.
|
||||||
|
tokens_db.init_schema(os.environ["USERS_DB_PATH"])
|
||||||
|
|
||||||
server.config.setdefault("API_TITLE", "colibre API")
|
server.config.setdefault("API_TITLE", "colibre API")
|
||||||
server.config.setdefault("API_VERSION", "v1")
|
server.config.setdefault("API_VERSION", "v1")
|
||||||
server.config.setdefault("OPENAPI_VERSION", "3.0.3")
|
server.config.setdefault("OPENAPI_VERSION", "3.0.3")
|
||||||
@@ -27,8 +35,4 @@ def init_api(server) -> None:
|
|||||||
api = Api(server)
|
api = Api(server)
|
||||||
api.register_blueprint(routes.bp)
|
api.register_blueprint(routes.bp)
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
from src.api import tracking
|
|
||||||
|
|
||||||
tracking.start_worker(os.environ["USERS_DB_PATH"])
|
tracking.start_worker(os.environ["USERS_DB_PATH"])
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ _MIGRATIONS: list[tuple[str, str]] = [
|
|||||||
"details TEXT, "
|
"details TEXT, "
|
||||||
"created_at TEXT NOT NULL)",
|
"created_at TEXT NOT NULL)",
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"0007_add_kind_to_api_tokens",
|
||||||
|
"ALTER TABLE api_tokens ADD COLUMN kind TEXT NOT NULL DEFAULT 'api'",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import sqlite3
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_api_creates_api_tokens_table(monkeypatch, tmp_path):
|
||||||
|
from flask import Flask
|
||||||
|
|
||||||
|
from src.api import init_api, tracking
|
||||||
|
|
||||||
|
db_path = tmp_path / "users.test.sqlite"
|
||||||
|
monkeypatch.setenv("USERS_DB_PATH", str(db_path))
|
||||||
|
server = Flask(__name__)
|
||||||
|
init_api(server)
|
||||||
|
try:
|
||||||
|
with sqlite3.connect(str(db_path)) as conn:
|
||||||
|
rows = conn.execute(
|
||||||
|
"SELECT name FROM sqlite_master "
|
||||||
|
"WHERE type='table' AND name='api_tokens'"
|
||||||
|
).fetchall()
|
||||||
|
finally:
|
||||||
|
tracking.stop_worker()
|
||||||
|
assert rows == [("api_tokens",)]
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
def test_migration_0007_adds_kind_to_legacy_api_tokens(monkeypatch, tmp_path):
|
||||||
|
from src import migrations
|
||||||
|
from src.auth import db as auth_db
|
||||||
|
from src.subscriptions import db as sub_db
|
||||||
|
|
||||||
|
db_path = tmp_path / "users.test.sqlite"
|
||||||
|
monkeypatch.setenv("USERS_DB_PATH", str(db_path))
|
||||||
|
auth_db.reset_conn_for_tests()
|
||||||
|
auth_db.init_schema()
|
||||||
|
sub_db.init_schema()
|
||||||
|
|
||||||
|
conn = auth_db.get_conn()
|
||||||
|
conn.execute("DROP TABLE IF EXISTS api_tokens")
|
||||||
|
# ancienne table SANS colonne kind
|
||||||
|
conn.execute(
|
||||||
|
"CREATE TABLE api_tokens ("
|
||||||
|
"id INTEGER PRIMARY KEY, token_hash TEXT NOT NULL UNIQUE, "
|
||||||
|
"label TEXT NOT NULL, user_id INTEGER, created_at TEXT NOT NULL, "
|
||||||
|
"last_used_at TEXT, count_total INTEGER NOT NULL DEFAULT 0, revoked_at TEXT)"
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
migrations.apply_pending()
|
||||||
|
cols = [r[1] for r in conn.execute("PRAGMA table_info(api_tokens)").fetchall()]
|
||||||
|
assert "kind" in cols
|
||||||
|
|
||||||
|
# idempotent : un second passage ne lève pas
|
||||||
|
migrations.apply_pending()
|
||||||
|
auth_db.reset_conn_for_tests()
|
||||||
Reference in New Issue
Block a user