feat: add author-username search to feed/gists/projects listings and partial-index migration
DevPlace CI / test (push) Failing after 2m5s

Extend `database.text_search_clause` with an `author_field` parameter that resolves username matches to user UIDs, enabling author-username search across the three public listings (`/feed`, `/gists`, `/projects`). Update the corresponding API docs and README route descriptions to reflect the new search scope. Add six partial indexes (`idx_comments_target_live`, `idx_votes_target_live`, `idx_reactions_target_live`, `idx_gists_live_created`, `idx_projects_live_created`, `idx_attachments_user_created_live`) to optimize filtered queries on non-deleted rows. Introduce a hot-settings cache (`_hot_settings`) with a 2-second TTL for `maintenance_mode`, `rate_limit_per_minute`, and `rate_limit_window_seconds`, plus a periodic rate-limit store sweep (`_sweep_rate_limit_store`) to evict stale IP entries every 60 seconds. Add `GZipMiddleware` to the FastAPI app for response compression.
This commit is contained in:
2026-06-19 22:24:51 +00:00
parent d10f1af118
commit e393722600
22 changed files with 269 additions and 52 deletions
+72
View File
@@ -522,3 +522,75 @@ def test_load_comments_drops_blocked_author(local_db):
others = load_comments("post", post_uid, None)
assert len(others) == 1
def test_get_uids_by_username_match_returns_matching_uids(local_db):
from devplacepy.database import get_uids_by_username_match
target = generate_uid()
get_table("users").insert(
{
"uid": target,
"username": "searchablehero",
"created_at": _now_db_helpers(),
}
)
assert target in get_uids_by_username_match("searchablehero")
assert target in get_uids_by_username_match("hablehe")
assert get_uids_by_username_match("") == []
def test_text_search_clause_matches_author_username(local_db):
from devplacepy.database import text_search_clause
author = generate_uid()
get_table("users").insert(
{
"uid": author,
"username": "authorquery",
"created_at": _now_db_helpers(),
}
)
post_uid = _post(author, title="unrelated title", content="unrelated body")
posts = get_table("posts")
clause = text_search_clause(
posts, "authorquery", ("title", "content"), author_field="user_uid"
)
assert clause is not None
rows = list(posts.find(clause, deleted_at=None))
assert post_uid in {r["uid"] for r in rows}
def test_text_search_clause_without_author_field_ignores_username(local_db):
from devplacepy.database import text_search_clause
author = generate_uid()
get_table("users").insert(
{
"uid": author,
"username": "lonelyauthor",
"created_at": _now_db_helpers(),
}
)
_post(author, title="nothing here", content="nothing here either")
posts = get_table("posts")
clause = text_search_clause(posts, "lonelyauthor", ("title", "content"))
rows = list(posts.find(clause, deleted_at=None)) if clause is not None else []
assert all(r["user_uid"] != author for r in rows)
def test_text_search_clause_still_matches_text_fields(local_db):
from devplacepy.database import text_search_clause
author = _user_db_helpers()
post_uid = _post(author, title="distinctivekeyword", content="body text")
posts = get_table("posts")
clause = text_search_clause(
posts, "distinctivekeyword", ("title", "content"), author_field="user_uid"
)
assert clause is not None
rows = list(posts.find(clause, deleted_at=None))
assert post_uid in {r["uid"] for r in rows}