feat: add seo_meta service for AI-generated SEO metadata with CLI management and database layer
DevPlace CI / test (push) Failing after 2m13s
DevPlace CI / test (push) Failing after 2m13s
Implement a new `SeoMetaService` subservice that generates clean SEO title/description/keywords for published content items, distinct from the existing SEO diagnostics auditor. Add `seo_metadata` polymorphic table with soft-delete support, batch query methods, and usage tracking. Extend the CLI with `seo-meta prune` and `seo-meta clear` commands for job row lifecycle management. Wire `schedule_seo_meta_for_table` into content creation and editing flows in `content.py`. Document the new service in `AGENTS.md` and `README.md`, including the `extra_head` site setting for custom `<head>` injection.
This commit is contained in:
@@ -50,3 +50,44 @@ def test_keyword_scores_rank_match_higher():
|
||||
assert scores
|
||||
best = max(scores, key=scores.get)
|
||||
assert "silicon" in next(c.text for c in chunks if c.uid == best).lower()
|
||||
|
||||
|
||||
def test_dims_reflects_embedding_width():
|
||||
store = VectorStore("ds_store_test_dims")
|
||||
try:
|
||||
chunks = _chunks()
|
||||
vectors = local_embed([c.text for c in chunks]).vectors
|
||||
store.add(chunks, vectors)
|
||||
assert store.dims == len(vectors[0])
|
||||
finally:
|
||||
store.drop()
|
||||
|
||||
|
||||
def test_coverage_analytics_empty_collection():
|
||||
store = VectorStore("ds_store_test_cov_empty")
|
||||
try:
|
||||
analytics = store.coverage_analytics()
|
||||
assert analytics == {
|
||||
"chunks": 0,
|
||||
"domains": 0,
|
||||
"sources": 0,
|
||||
"avg_chunk_chars": 0,
|
||||
}
|
||||
finally:
|
||||
store.drop()
|
||||
|
||||
|
||||
def test_coverage_analytics_counts_chunks_and_sources():
|
||||
store = VectorStore("ds_store_test_cov")
|
||||
try:
|
||||
chunks = _chunks()
|
||||
for index, chunk in enumerate(chunks):
|
||||
chunk.source = "httpx" if index == 0 else "playwright"
|
||||
vectors = local_embed([c.text for c in chunks]).vectors
|
||||
store.add(chunks, vectors)
|
||||
analytics = store.coverage_analytics()
|
||||
assert analytics["chunks"] == 3
|
||||
assert analytics["sources"] == 2
|
||||
assert analytics["avg_chunk_chars"] > 0
|
||||
finally:
|
||||
store.drop()
|
||||
|
||||
Reference in New Issue
Block a user