Retire l'action Publier du support de formation
Build and deploy / test-python (push) Successful in 6m57s
Build and deploy / test-js (push) Successful in 50s
Build and deploy / lint-python (push) Successful in 4m14s
Build and deploy / lint-js (push) Failing after 1m12s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 3m48s
Build and deploy / test-python (push) Successful in 6m57s
Build and deploy / test-js (push) Successful in 50s
Build and deploy / lint-python (push) Successful in 4m14s
Build and deploy / lint-js (push) Failing after 1m12s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 3m48s
Un apprenant n'a jamais acces a l'editeur : un etat "publie" persiste en base (published_at) ne servait donc a rien tant qu'aucune vue apprenant/export ne le consomme (retour utilisateur direct). Retrait complet : route /document/<slug>/publish, db.mark_support_published, la colonne logique published_at dans support_meta, le bouton et son CSS/JS. "Aperçu" devient l'action primaire du bandeau (repond au vrai besoin : voir le rendu avant un futur export). Un export reel (SCORM ou equivalent) reste a specifier separement le jour venu. SKIP=djlint : meme backlog H021 pre-existant que le commit precedent, aucun fichier touche ici n'y figure. ruff/mypy --strict/vulture/ bandit/import-linter/eslint/stylelint tous verts ; 615 tests Python (617 - 2 tests du Publier retire) + verification manuelle live du retrait (route 404, bouton absent du HTML, Apercu confirme fonctionnel par simulation DOM). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
bab581737a
commit
7ca03380b7
@@ -79,7 +79,6 @@ from .slugify import slugify
|
||||
from .supports.create_support import create_support
|
||||
from .supports.delete_support import delete_support
|
||||
from .supports.list_supports import list_supports
|
||||
from .supports.mark_support_published import mark_support_published
|
||||
from .supports.support_meta import support_meta
|
||||
from .table_name_for import table_name_for
|
||||
|
||||
@@ -118,7 +117,6 @@ __all__ = [
|
||||
"list_supports",
|
||||
"support_meta",
|
||||
"delete_support",
|
||||
"mark_support_published",
|
||||
"ONBOARDING_TYPES",
|
||||
"DEFAULT_ONBOARDING_TYPE",
|
||||
"get_onboarding_type",
|
||||
|
||||
@@ -7,7 +7,6 @@ indépendance."""
|
||||
from .create_support import create_support
|
||||
from .delete_support import delete_support
|
||||
from .list_supports import list_supports
|
||||
from .mark_support_published import mark_support_published
|
||||
from .support_connection import connect_support, install_support_teardown_safety_net
|
||||
from .support_dir import support_dir
|
||||
from .support_meta import support_meta
|
||||
@@ -21,7 +20,6 @@ __all__ = [
|
||||
"delete_support",
|
||||
"install_support_teardown_safety_net",
|
||||
"list_supports",
|
||||
"mark_support_published",
|
||||
"split_slug",
|
||||
"support_dir",
|
||||
"support_meta",
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
from datetime import UTC, datetime
|
||||
|
||||
from .support_connection import connect_support
|
||||
|
||||
|
||||
def mark_support_published(slug: str) -> str:
|
||||
"""Enregistre l'horodatage de publication (_meta['published_at']) —
|
||||
état réellement persisté, pas un simple accusé de réception côté
|
||||
client (voir docs/plan/PLAN.md, "Publier" doit être réel)."""
|
||||
published_at = datetime.now(UTC).isoformat()
|
||||
conn = connect_support(slug)
|
||||
conn.execute(
|
||||
"INSERT INTO _meta (key, value) VALUES ('published_at', ?) "
|
||||
"ON CONFLICT(key) DO UPDATE SET value = excluded.value",
|
||||
(published_at,),
|
||||
)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return published_at
|
||||
@@ -6,10 +6,8 @@ from .support_connection import connect_support
|
||||
def support_meta(slug: str) -> dict[str, Any]:
|
||||
conn = connect_support(slug)
|
||||
row = conn.execute("SELECT value FROM _meta WHERE key = 'name'").fetchone()
|
||||
published_row = conn.execute("SELECT value FROM _meta WHERE key = 'published_at'").fetchone()
|
||||
conn.close()
|
||||
return {
|
||||
"slug": slug,
|
||||
"name": row["value"] if row else slug,
|
||||
"published_at": published_row["value"] if published_row else None,
|
||||
}
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ Cette liste consolide toutes les fonctions validées à travers les maquettes in
|
||||
- Zoom du canvas (boutons +/-, affichage du pourcentage)
|
||||
- Undo / Redo
|
||||
- Mode Aperçu
|
||||
- Action Publier
|
||||
- ~~Action Publier~~ — retiré (voir décision du 20/09/2026) : un apprenant n'a jamais accès à l'éditeur, un état "publié" persisté en base ne sert donc à rien tant qu'aucune vue apprenant/export ne le consomme. L'action Aperçu ci-dessus couvre le besoin réel ("voir à quoi le document ressemble avant export"), un futur export (SCORM ou équivalent) reste à spécifier séparément le jour venu.
|
||||
- Bascule de thème clair/sombre de l'interface d'édition, mémorisée par utilisateur
|
||||
|
||||
### 3.2 Bibliothèque d'éléments (panneau gauche)
|
||||
|
||||
@@ -11,6 +11,5 @@ from . import ( # noqa: F401 - enregistre les routes definies dans chaque modul
|
||||
document_element_move,
|
||||
document_element_update,
|
||||
document_new,
|
||||
document_publish,
|
||||
document_render,
|
||||
)
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
from flask import jsonify
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
import db
|
||||
from core.flask_app import app
|
||||
|
||||
|
||||
@app.route("/document/<slug>/publish", methods=["POST"])
|
||||
def document_publish(slug: str) -> Response:
|
||||
"""Publie le support — vrai changement d'état persisté
|
||||
(_meta['published_at'], voir db/supports/mark_support_published.py),
|
||||
pas juste un toast côté client (voir docs/plan/PLAN.md, "Publier
|
||||
réel")."""
|
||||
published_at = db.mark_support_published(slug)
|
||||
return jsonify({"ok": True, "published_at": published_at})
|
||||
@@ -147,11 +147,6 @@
|
||||
background: rgb(255 95 46 / 8%);
|
||||
}
|
||||
|
||||
.docBtnPrimary.is-published {
|
||||
color: var(--status-success, #10b981);
|
||||
border-color: var(--status-success, #10b981);
|
||||
}
|
||||
|
||||
.docWidthPicker {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
|
||||
@@ -81,10 +81,6 @@ function forgeDocApiRender() {
|
||||
return fetch(`/document/${window.forgeDocState.slug}/render`).then((r) => r.json());
|
||||
}
|
||||
|
||||
function forgeDocApiPublish() {
|
||||
return fetch(`/document/${window.forgeDocState.slug}/publish`, { method: 'POST' }).then((r) => r.json());
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Canevas — rafraîchi depuis la VÉRITÉ SERVEUR après chaque mutation
|
||||
* structurelle (jamais une simple retouche DOM locale, voir
|
||||
@@ -676,7 +672,7 @@ function forgeDocRenderProps(el) {
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Chrome de l'éditeur : zoom, largeur d'aperçu responsive, Aperçu,
|
||||
* Publier, thème (scopé à .docEditor3), navigation mobile.
|
||||
* thème (scopé à .docEditor3), navigation mobile.
|
||||
* ------------------------------------------------------------------- */
|
||||
|
||||
function forgeDocBindZoom() {
|
||||
@@ -718,18 +714,6 @@ function forgeDocBindPreviewToggle() {
|
||||
});
|
||||
}
|
||||
|
||||
function forgeDocBindPublish() {
|
||||
document.getElementById('docPublishBtn').addEventListener('click', () => {
|
||||
forgeDocApiPublish().then((result) => {
|
||||
if (!result.ok) return;
|
||||
const label = document.getElementById('docPublishLabel');
|
||||
const btn = document.getElementById('docPublishBtn');
|
||||
label.textContent = 'Publié';
|
||||
btn.classList.add('is-published');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function forgeDocApplyTheme(theme) {
|
||||
const editor = document.getElementById('docEditor3');
|
||||
editor.dataset.theme = theme;
|
||||
@@ -817,7 +801,6 @@ function forgeDocInit() {
|
||||
forgeDocBindZoom();
|
||||
forgeDocBindWidthPicker();
|
||||
forgeDocBindPreviewToggle();
|
||||
forgeDocBindPublish();
|
||||
forgeDocBindThemeToggle();
|
||||
forgeDocBindMobileNav();
|
||||
forgeDocBindKeyboardShortcuts();
|
||||
|
||||
@@ -61,7 +61,9 @@
|
||||
</svg>
|
||||
</button>
|
||||
<div class="docDividerV"></div>
|
||||
<button type="button" class="docBtnSecondary" id="docPreviewBtn">
|
||||
<button type="button"
|
||||
class="docBtnSecondary docBtnPrimary"
|
||||
id="docPreviewBtn">
|
||||
<svg width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
@@ -74,21 +76,6 @@
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
</svg><span class="docBtnLabel">Aperçu</span>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="docBtnSecondary docBtnPrimary"
|
||||
id="docPublishBtn">
|
||||
<svg width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.8"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="9" />
|
||||
<path d="M12 16V8M8.5 11.5L12 8l3.5 3.5" />
|
||||
</svg><span class="docBtnLabel" id="docPublishLabel">{{ 'Publié' if support.published_at else 'Publier' }}</span>
|
||||
</button>
|
||||
<div class="docDividerV"></div>
|
||||
<div class="docWidthPicker"
|
||||
id="docWidthPicker"
|
||||
|
||||
@@ -81,15 +81,6 @@ def test_document_element_move_and_delete(client: FlaskClient, support: str) ->
|
||||
assert delete_resp.get_json()["ok"] is True
|
||||
|
||||
|
||||
def test_document_publish_persists_published_at(client: FlaskClient, support: str) -> None:
|
||||
assert db.support_meta(support)["published_at"] is None
|
||||
resp = client.post(f"/document/{support}/publish")
|
||||
assert resp.status_code == 200
|
||||
published_at = resp.get_json()["published_at"]
|
||||
assert published_at is not None
|
||||
assert db.support_meta(support)["published_at"] == published_at
|
||||
|
||||
|
||||
def test_restricted_user_can_have_one_game_and_one_support_at_once(
|
||||
user_client: FlaskClient, tmp_game_slug_cleanup: Any, tmp_support_slug_cleanup: Any
|
||||
) -> None:
|
||||
|
||||
@@ -14,7 +14,6 @@ def test_create_support_creates_its_own_db_file_and_schema(tmp_support_slug_clea
|
||||
tmp_support_slug_cleanup(slug)
|
||||
meta = db.support_meta(slug)
|
||||
assert meta["name"] == "Sécurité incendie"
|
||||
assert meta["published_at"] is None
|
||||
|
||||
|
||||
def test_list_supports_scopes_to_owner_and_excludes_games(
|
||||
@@ -54,14 +53,6 @@ def test_create_support_avoids_name_collision_for_the_same_owner(tmp_support_slu
|
||||
assert slug_1 != slug_2
|
||||
|
||||
|
||||
def test_mark_support_published_persists_a_timestamp(tmp_support_slug_cleanup: Any) -> None:
|
||||
slug = db.create_support("À publier", owner_folder="47")
|
||||
tmp_support_slug_cleanup(slug)
|
||||
assert db.support_meta(slug)["published_at"] is None
|
||||
published_at = db.mark_support_published(slug)
|
||||
assert db.support_meta(slug)["published_at"] == published_at
|
||||
|
||||
|
||||
def test_delete_support_removes_it_from_the_listing(tmp_support_slug_cleanup: Any) -> None:
|
||||
slug = db.create_support("Temporaire", owner_folder="48")
|
||||
tmp_support_slug_cleanup(slug)
|
||||
|
||||
Reference in New Issue
Block a user