feat: add ISSLOP AI usage analysis CLI commands, game router, and politics topic

- Add `cmd_isslop_prune`, `cmd_isslop_clear`, `cmd_isslop_analyze` CLI commands for AI usage analysis job management
- Register `/game` router with `index` and `farm` endpoints for Code Farm idle game
- Add `politics` to allowed TOPICS constant replacing `signals`
- Introduce `ISSLOP_DIR`, `ISSLOP_WORKSPACES_DIR`, `ISSLOP_RUNS_DIR`, `ISSLOP_MEDIA_DIR` config paths
- Add `clear_user_stars` and `clear_user_projects_cache` calls on vote and project create/delete
- Update `make prod` to use `nproc` workers via `DEVPLACE_WEB_WORKERS` env var
- Convert `database.py` and `utils.py` to packages for modular structure
- Add `devplace apikey` and `devplace token` CLI subcommands for API key and access token management
This commit is contained in:
2026-07-06 03:57:47 +00:00
parent f1bdefd834
commit 9a8046ab2a
110 changed files with 1466 additions and 374 deletions
+120
View File
@@ -37,9 +37,11 @@ def init_db():
_index(db, "users", "idx_users_api_key", ["api_key"])
_index(db, "users", "idx_users_role", ["role", "created_at"])
_index(db, "users", "idx_users_last_seen", ["last_seen"])
_index(db, "users", "idx_users_created_at", ["created_at"])
_index(db, "posts", "idx_posts_user_uid", ["user_uid"])
_index(db, "posts", "idx_posts_created_at", ["created_at"])
_index(db, "posts", "idx_posts_topic", ["topic"])
_index(db, "posts", "idx_posts_slug", ["slug"])
if "posts" in tables:
posts_table = get_table("posts")
if not posts_table.has_column("tags"):
@@ -120,6 +122,15 @@ def init_db():
_index(db, "votes", "idx_votes_target", ["target_uid", "target_type"])
_index(db, "messages", "idx_messages_sender", ["sender_uid"])
_index(db, "messages", "idx_messages_receiver", ["receiver_uid"])
_index(
db, "messages", "idx_messages_conversation", ["sender_uid", "receiver_uid"]
)
_index(
db,
"messages",
"idx_messages_conversation_rev",
["receiver_uid", "sender_uid"],
)
_index(db, "notifications", "idx_notifications_user", ["user_uid"])
_index(db, "notifications", "idx_notifications_user_read", ["user_uid", "read"])
_index(db, "push_registration", "idx_push_registration_user", ["user_uid"])
@@ -140,6 +151,7 @@ def init_db():
projects.create_column_by_example(column, example)
_index(db, "projects", "idx_projects_user", ["user_uid"])
_index(db, "projects", "idx_projects_slug", ["slug"])
_index(db, "projects", "idx_projects_private", ["is_private"])
_index(db, "projects", "idx_projects_stars", ["stars"])
_index(db, "projects", "idx_projects_type", ["project_type"])
@@ -170,6 +182,7 @@ def init_db():
db, "project_files", "idx_project_files_parent", ["project_uid", "parent_path"]
)
_index(db, "badges", "idx_badges_user", ["user_uid"])
_index(db, "badges", "idx_badges_user_name", ["user_uid", "badge_name"])
_index(db, "follows", "idx_follows_follower", ["follower_uid"])
_index(db, "follows", "idx_follows_following", ["following_uid"])
user_relations = get_table("user_relations")
@@ -189,6 +202,7 @@ def init_db():
_index(db, "password_resets", "idx_password_resets_token", ["token"])
_index(db, "gists", "idx_gists_user_uid", ["user_uid"])
_index(db, "gists", "idx_gists_language", ["language"])
_index(db, "gists", "idx_gists_slug", ["slug"])
attachments = get_table("attachments")
for column, example in (
("uid", ""),
@@ -244,6 +258,7 @@ def init_db():
db["site_settings"].insert(
{"uid": f"default_{key}", "key": key, "value": value}
)
_index(db, "site_settings", "idx_site_settings_key", ["key"])
news = get_table("news")
for column, example in (
@@ -272,6 +287,7 @@ def init_db():
news.create_column_by_example(column, example)
_index(db, "news", "idx_news_external_id", ["external_id"])
_index(db, "news", "idx_news_slug", ["slug"])
_index(db, "news", "idx_news_synced_at", ["synced_at"])
_index(db, "news", "idx_news_status", ["status"])
_index(db, "news", "idx_news_featured", ["featured"])
@@ -457,6 +473,8 @@ def init_db():
instances.create_column_by_example(column, example)
_index(db, "instances", "idx_instances_project", ["project_uid"])
_index(db, "instances", "idx_instances_slug", ["slug"])
_index(db, "instances", "idx_instances_name", ["name"])
_index(db, "instances", "idx_instances_state", ["desired_state", "status"])
_index(db, "instances", "idx_instances_container", ["container_id"])
_index(db, "instances", "idx_instances_ingress", ["ingress_slug"])
@@ -791,6 +809,108 @@ def init_db():
deepsearch_url_cache.create_column_by_example(column, example)
_index(db, "deepsearch_url_cache", "idx_deepsearch_url_cache_hash", ["url_hash"])
isslop_analyses = get_table("isslop_analyses")
for column, example in (
("uid", ""),
("owner_kind", ""),
("owner_id", ""),
("source_url", ""),
("source_kind", ""),
("status", ""),
("created_at", ""),
("finished_at", ""),
("content_hash", ""),
("grade", ""),
("slop_score", 0.0),
("origin_score", 0.0),
("quality_deficit_score", 0.0),
("human_percent", 0.0),
("ai_percent", 0.0),
("category", ""),
("confidence", ""),
("files_total", 0),
("files_analyzed", 0),
("error_message_text", ""),
("detected_builder", ""),
("dom_slop_score", 0.0),
("deleted_at", ""),
("deleted_by", ""),
):
if not isslop_analyses.has_column(column):
isslop_analyses.create_column_by_example(column, example)
_index(db, "isslop_analyses", "idx_isslop_analyses_owner", ["owner_kind", "owner_id", "created_at"])
_index(db, "isslop_analyses", "idx_isslop_analyses_status", ["status"])
_index(db, "isslop_analyses", "idx_isslop_analyses_hash", ["content_hash"])
isslop_events = get_table("isslop_events")
for column, example in (
("analysis_uid", ""),
("seq", 0),
("kind", ""),
("message", ""),
("payload", ""),
("created_at", ""),
):
if not isslop_events.has_column(column):
isslop_events.create_column_by_example(column, example)
_index(db, "isslop_events", "idx_isslop_events_analysis", ["analysis_uid", "seq"])
isslop_file_results = get_table("isslop_file_results")
for column, example in (
("analysis_uid", ""),
("path", ""),
("language", ""),
("lines", 0),
("origin_score", 0.0),
("quality_deficit_score", 0.0),
("category", ""),
("signals", ""),
("source", ""),
):
if not isslop_file_results.has_column(column):
isslop_file_results.create_column_by_example(column, example)
_index(db, "isslop_file_results", "idx_isslop_file_results_analysis", ["analysis_uid"])
isslop_image_results = get_table("isslop_image_results")
for column, example in (
("analysis_uid", ""),
("path", ""),
("ai_probability", 0.0),
("grade", ""),
("verdict", ""),
("image_kind", ""),
("tells", ""),
("description", ""),
("thumb", ""),
):
if not isslop_image_results.has_column(column):
isslop_image_results.create_column_by_example(column, example)
_index(db, "isslop_image_results", "idx_isslop_image_results_analysis", ["analysis_uid"])
isslop_dom_results = get_table("isslop_dom_results")
for column, example in (
("analysis_uid", ""),
("url", ""),
("detected_builder", ""),
("signal_count", 0),
("screenshot", ""),
("signals", ""),
):
if not isslop_dom_results.has_column(column):
isslop_dom_results.create_column_by_example(column, example)
_index(db, "isslop_dom_results", "idx_isslop_dom_results_analysis", ["analysis_uid"])
isslop_reports = get_table("isslop_reports")
for column, example in (
("analysis_uid", ""),
("markdown", ""),
("model_used", ""),
("generated_at", ""),
):
if not isslop_reports.has_column(column):
isslop_reports.create_column_by_example(column, example)
_index(db, "isslop_reports", "idx_isslop_reports_analysis", ["analysis_uid"], unique=True)
game_farms = get_table("game_farms")
for column, example in (
("uid", ""),