Decoupling audit: remove coop_api, fix blog admin calendar imports
Some checks are pending
Build and Deploy / build-and-deploy (push) Waiting to run

- Delete coop_api.py (dead internal API endpoint)
- Replace cross-app calendar imports with shared service calls
- Update shared submodule

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
giles
2026-02-20 11:15:23 +00:00
parent 2dc9bf220b
commit a8e0d8f257
5 changed files with 12 additions and 71 deletions

4
app.py
View File

@@ -16,7 +16,6 @@ from bp import (
register_admin, register_admin,
register_menu_items, register_menu_items,
register_snippets, register_snippets,
register_coop_api,
) )
@@ -78,9 +77,6 @@ def create_app() -> "Quart":
app.register_blueprint(register_menu_items()) app.register_blueprint(register_menu_items())
app.register_blueprint(register_snippets()) app.register_blueprint(register_snippets())
# Internal API (server-to-server, CSRF-exempt)
app.register_blueprint(register_coop_api())
# --- KV admin endpoints --- # --- KV admin endpoints ---
@app.get("/settings/kv/<key>") @app.get("/settings/kv/<key>")
async def kv_get(key: str): async def kv_get(key: str):

View File

@@ -3,4 +3,3 @@ from .blog.routes import register as register_blog_bp
from .admin.routes import register as register_admin from .admin.routes import register as register_admin
from .menu_items.routes import register as register_menu_items from .menu_items.routes import register as register_menu_items
from .snippets.routes import register as register_snippets from .snippets.routes import register as register_snippets
from .coop_api import register as register_coop_api

View File

@@ -1,51 +0,0 @@
"""
Internal JSON API for the coop app.
These endpoints are called by other apps (market, cart) over HTTP
to fetch Ghost CMS content without importing blog services.
"""
from __future__ import annotations
from quart import Blueprint, g, jsonify
from shared.browser.app.csrf import csrf_exempt
def register() -> Blueprint:
bp = Blueprint("coop_api", __name__, url_prefix="/internal")
@bp.get("/post/<slug>")
@csrf_exempt
async def post_by_slug(slug: str):
"""
Return a Ghost post's key fields by slug.
Called by market app for the landing page.
"""
from bp.blog.ghost_db import DBClient
client = DBClient(g.s)
posts = await client.posts_by_slug(slug, include_drafts=False)
if not posts:
return jsonify(None), 404
post, original_post = posts[0]
return jsonify(
{
"post": {
"id": post.get("id"),
"title": post.get("title"),
"html": post.get("html"),
"custom_excerpt": post.get("custom_excerpt"),
"feature_image": post.get("feature_image"),
"slug": post.get("slug"),
},
"original_post": {
"id": getattr(original_post, "id", None),
"title": getattr(original_post, "title", None),
},
}
)
return bp

View File

@@ -191,13 +191,12 @@ def register():
@require_admin @require_admin
async def calendar_view(slug: str, calendar_id: int): async def calendar_view(slug: str, calendar_id: int):
"""Show calendar month view for browsing entries""" """Show calendar month view for browsing entries"""
from shared.models.calendars import Calendar # TODO: service method when admin UI is reworked from shared.models.calendars import Calendar
from shared.utils.calendar_helpers import parse_int_arg, add_months, build_calendar_weeks
from shared.services.registry import services
from sqlalchemy import select from sqlalchemy import select
from datetime import datetime, timezone from datetime import datetime, timezone
from quart import request
import calendar as pycalendar import calendar as pycalendar
from ...calendar.services.calendar_view import parse_int_arg, add_months, build_calendar_weeks
from ...calendar.services import get_visible_entries_for_period
from quart import session as qsession from quart import session as qsession
from ..services.entry_associations import get_post_entry_ids from ..services.entry_associations import get_post_entry_ids
@@ -235,15 +234,13 @@ def register():
period_end = datetime(next_y, next_m, 1, tzinfo=timezone.utc) period_end = datetime(next_y, next_m, 1, tzinfo=timezone.utc)
user = getattr(g, "user", None) user = getattr(g, "user", None)
user_id = user.id if user else None
is_admin = bool(user and getattr(user, "is_admin", False))
session_id = qsession.get("calendar_sid") session_id = qsession.get("calendar_sid")
visible = await get_visible_entries_for_period( month_entries = await services.calendar.visible_entries_for_period(
sess=g.s, g.s, calendar_obj.id, period_start, period_end,
calendar_id=calendar_obj.id, user_id=user_id, is_admin=is_admin, session_id=session_id,
period_start=period_start,
period_end=period_end,
user=user,
session_id=session_id,
) )
# Get associated entry IDs for this post # Get associated entry IDs for this post
@@ -264,7 +261,7 @@ def register():
next_month_year=next_month_year, next_month_year=next_month_year,
prev_year=prev_year, prev_year=prev_year,
next_year=next_year, next_year=next_year,
month_entries=visible.merged_entries, month_entries=month_entries,
associated_entry_ids=associated_entry_ids, associated_entry_ids=associated_entry_ids,
) )
return await make_response(html) return await make_response(html)
@@ -273,7 +270,7 @@ def register():
@require_admin @require_admin
async def entries(slug: str): async def entries(slug: str):
from ..services.entry_associations import get_post_entry_ids from ..services.entry_associations import get_post_entry_ids
from shared.models.calendars import Calendar # TODO: service method when admin UI is reworked from shared.models.calendars import Calendar
from sqlalchemy import select from sqlalchemy import select
post_id = g.post_data["post"]["id"] post_id = g.post_data["post"]["id"]
@@ -309,7 +306,7 @@ def register():
@require_admin @require_admin
async def toggle_entry(slug: str, entry_id: int): async def toggle_entry(slug: str, entry_id: int):
from ..services.entry_associations import toggle_entry_association, get_post_entry_ids, get_associated_entries from ..services.entry_associations import toggle_entry_association, get_post_entry_ids, get_associated_entries
from shared.models.calendars import Calendar # TODO: service method when admin UI is reworked from shared.models.calendars import Calendar
from sqlalchemy import select from sqlalchemy import select
from quart import jsonify from quart import jsonify

2
shared

Submodule shared updated: 7ee8638d6e...e83df2f742