From 8d695481896deb875a22e185498049adf4d206be Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Tue, 29 Sep 2026 21:25:32 -0300 Subject: [PATCH 01/10] split cache helpers into frame and build modules --- graphify-out/manifest.json | 4 +- main/app/stocks_api/build.py | 177 ++++++++++++++++++++++++++ main/app/stocks_api/cache.py | 237 ++++++----------------------------- main/app/stocks_api/frame.py | 64 ++++++++++ 4 files changed, 282 insertions(+), 200 deletions(-) create mode 100644 main/app/stocks_api/build.py create mode 100644 main/app/stocks_api/frame.py diff --git a/graphify-out/manifest.json b/graphify-out/manifest.json index 2818a84b..90b9dca6 100644 --- a/graphify-out/manifest.json +++ b/graphify-out/manifest.json @@ -300,8 +300,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\stocks_api\\key.py": { - "mtime": 1790726217.7849143, - "ast_hash": "f7794d72a5abb5ac335b444be95ffd4e", + "mtime": 1790727540.9697123, + "ast_hash": "60821b4bf959fd817a917d48956a59d4", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\stocks_api\\query.py": { diff --git a/main/app/stocks_api/build.py b/main/app/stocks_api/build.py new file mode 100644 index 00000000..57381734 --- /dev/null +++ b/main/app/stocks_api/build.py @@ -0,0 +1,177 @@ +"""Feather build / read helpers for the stocks cache. + +Owns the on-disk layout (CACHE_*_PATH) and the DB-to-feather build. +Imports from frame.py only — never from cache.py at module load, so the +load-time graph stays acyclic (cache -> build -> frame). + +Runtime config (engine + paths) is resolved via the cache module at call +time (_runtimeConf): tests rebind stocksEngine / CACHE_*_PATH on +main.app.stocks_api.cache, and reading them there keeps those patch +sites working with zero behavior change in production. +""" + +import logging +import os +import sys +from pathlib import Path +from typing import Any + +import pandas as pd +import pyarrow as pa +import pyarrow.feather as feather +import zstandard as zstd +from sqlalchemy.engine import Engine +from sqlalchemy.exc import OperationalError +from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_exponential + +from config import stocksEngine as _fallbackStocksEngine +from main.app.stocks_api.frame import ( + CATEGORY_COLS, + PRESORTED_FLAG_KEY, + arrowTypeFor, + optimizeDtypes, +) +from main.app.stocks_api.util import JSON_COLUMNS + +fcntl: Any = None +if sys.platform != "win32": + import fcntl + +logger = logging.getLogger(__name__) + +CACHE_FEATHER_PATH = Path("/app/cache/stocks_cache.feather") +CACHE_NESTED_PATH = Path("/app/cache/stocks_nested.feather") + + +def _runtimeConf() -> tuple: + """Return (engine, featherPath, nestedPath), preferring live values on + the cache module (where tests monkeypatch) over this module's defaults.""" + import main.app.stocks_api.cache as cacheMod + + engine = getattr(cacheMod, "stocksEngine", None) or _fallbackStocksEngine + featherPath = getattr(cacheMod, "CACHE_FEATHER_PATH", CACHE_FEATHER_PATH) + nestedPath = getattr(cacheMod, "CACHE_NESTED_PATH", CACHE_NESTED_PATH) + return engine, featherPath, nestedPath + + +@retry( + stop=stop_after_attempt(3), + wait=wait_exponential(), + retry=retry_if_exception_type(OperationalError), + reraise=True, +) +def buildFeatherCache(engine: Engine | None = None): + sampleCols = None + sampleParts: dict[str, pd.Series] = {} + compressor = zstd.ZstdCompressor(level=3) + + defaultEngine, featherPath, nestedPath = _runtimeConf() + featherPath.parent.mkdir(parents=True, exist_ok=True) + tmpNested = nestedPath.with_suffix(".tmp") + tmpMain = featherPath.with_suffix(".tmp") + + writer = None + sink = None + schema = None + total = 0 + resolvedEngine = engine if engine is not None else defaultEngine + try: + with resolvedEngine.connect() as conn: + try: + typeRows = conn.exec_driver_sql("SHOW COLUMNS FROM b3_stocks").fetchall() + colTypes = {r[0]: str(r[1]).lower().split("(")[0].strip() for r in typeRows} + except Exception: + colTypes = {} + stream = conn.execution_options(stream_results=True) + result = stream.exec_driver_sql("SELECT * FROM b3_stocks ORDER BY TICKER ASC, TIME DESC") + try: + columns = list(result.keys()) + while True: + batch = result.fetchmany(2000) + if not batch: + break + chunk = pd.DataFrame.from_records((tuple(r) for r in batch), columns=columns) + if sampleCols is None: + sampleCols = [c for c in JSON_COLUMNS if c in chunk.columns] + for col in sampleCols or (): + if col not in sampleParts: + nonNull = chunk[col].dropna() + if not nonNull.empty: + sampleParts[col] = nonNull.head(20).reset_index(drop=True) + chunk[col] = chunk[col].map( + lambda s: compressor.compress(s.encode("utf-8")) if isinstance(s, str) else None + ) + chunk = optimizeDtypes(chunk) + + for col in CATEGORY_COLS: + if col in chunk.columns and str(chunk[col].dtype) == "category": + chunk[col] = chunk[col].astype(str) + if schema is None: + t0 = pa.Table.from_pandas(chunk, preserve_index=False) + fields = [] + for n in t0.column_names: + t = t0.schema.field(n).type + if n in (sampleCols or ()): + fields.append(pa.field(n, pa.binary())) + elif pa.types.is_null(t): + fields.append(pa.field(n, arrowTypeFor(colTypes.get(n, "varchar")))) + else: + fields.append(pa.field(n, t)) + schema = pa.schema(fields).with_metadata({PRESORTED_FLAG_KEY: b"1"}) + sink = pa.OSFile(str(tmpMain), "wb") + writer = pa.ipc.new_file(sink, schema) + assert writer is not None # nosec: B101 mypy narrowing, writer assigned just above + table = pa.Table.from_pandas(chunk, schema=schema, preserve_index=False) + writer.write_table(table) + total += len(chunk) + del chunk, table + finally: + try: + result.close() + except Exception: + pass # nosec: B110 best-effort writer/sink close, retried next refresh + except OperationalError: + logger.warning("feather build lost connection, retrying with fresh connection") + try: + resolvedEngine.dispose() + except Exception: + pass # nosec: B110 dispose is best-effort, original error re-raised below + raise + finally: + if writer is not None: + writer.close() + if sink is not None: + sink.close() + + nestedSample = pd.DataFrame(sampleParts) if sampleParts else None + if nestedSample is not None: + nestedSample.to_feather(tmpNested) + os.replace(tmpNested, nestedPath) + if writer is not None: + os.replace(tmpMain, featherPath) + logger.info(f"feather written to {featherPath} ({total} records)") + + +def tryBuildLock(): + if fcntl is None: + return open(os.devnull, "w") + _, featherPath, _ = _runtimeConf() + lockPath = featherPath.parent / "refresh.lock" + try: + lockPath.parent.mkdir(parents=True, exist_ok=True) + lockFile = open(lockPath, "w") + except OSError: + return open(os.devnull, "w") + try: + fcntl.flock(lockFile, fcntl.LOCK_EX | fcntl.LOCK_NB) + return lockFile + except OSError: + lockFile.close() + return None + + +def readFeatherDataFrame(path: Path) -> tuple[pd.DataFrame, bool]: + table = feather.read_table(path, memory_map=True) + presorted = (table.schema.metadata or {}).get(PRESORTED_FLAG_KEY) == b"1" + df = table.to_pandas(split_blocks=True, types_mapper=pd.ArrowDtype) + return df, presorted diff --git a/main/app/stocks_api/cache.py b/main/app/stocks_api/cache.py index 17d8d41d..95f0af98 100644 --- a/main/app/stocks_api/cache.py +++ b/main/app/stocks_api/cache.py @@ -1,214 +1,55 @@ import logging -from config import stocksEngine -from main.app.stocks_api.util import JSON_COLUMNS -import orjson -import threading - -import pandas as pd -import numpy as np -import pyarrow as pa -import pyarrow.feather as feather - -from sqlalchemy.engine import Engine -from sqlalchemy.exc import OperationalError -from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_exponential - import os -import subprocess # nosec: B404 used only with constant args, see line 302 +import subprocess # nosec: B404 used only with constant args, see getCachedStocks import sys +import threading import time -import zstandard as zstd from datetime import datetime, timezone -from pathlib import Path -from typing import Any -from main.utils.scheduler import registerJob +import pandas as pd +from sqlalchemy.engine import Engine + +from config import stocksEngine from main.app.stocks_api import compress, sync_cache +from main.app.stocks_api.build import ( + CACHE_FEATHER_PATH, + CACHE_NESTED_PATH, + buildFeatherCache, + readFeatherDataFrame, + tryBuildLock, +) +from main.app.stocks_api.frame import ( + CATEGORY_COLS, + PRESORTED_FLAG_KEY, + arrowTypeFor, + buildTickerIndex, + optimizeDtypes, + sortCacheFrame, +) +from main.utils.scheduler import registerJob -fcntl: Any = None -if sys.platform != "win32": - import fcntl +__all__ = [ + "CACHE_FEATHER_PATH", + "CACHE_LOAD_LOCK", + "CACHE_NESTED_PATH", + "CATEGORY_COLS", + "PRESORTED_FLAG_KEY", + "STALE_AFTER_SECONDS", + "StocksCacheManager", + "arrowTypeFor", + "buildFeatherCache", + "buildTickerIndex", + "optimizeDtypes", + "readFeatherDataFrame", + "sortCacheFrame", + "stocksCache", + "tryBuildLock", +] logger = logging.getLogger(__name__) -CATEGORY_COLS = frozenset(["TICKER", "NOME"]) - -CACHE_FEATHER_PATH = Path("/app/cache/stocks_cache.feather") -CACHE_NESTED_PATH = Path("/app/cache/stocks_nested.feather") STALE_AFTER_SECONDS = 6 * 3600 CACHE_LOAD_LOCK = threading.Lock() -PRESORTED_FLAG_KEY = b"b3_presorted" - - -def optimizeDtypes(df: pd.DataFrame) -> pd.DataFrame: - for col in CATEGORY_COLS: - if col in df.columns: - df[col] = df[col].astype("category") - - for col in df.select_dtypes(include=["float64"]).columns: - df[col] = pd.to_numeric(df[col], downcast="float") - - try: - for col in df.columns: - if str(df[col].dtype) not in ("object", "str"): - continue - if col not in CATEGORY_COLS and col not in JSON_COLUMNS and df[col].notna().all(): - df[col] = df[col].astype("string[pyarrow]") - except Exception as e: - logger.debug(f"Arrow string optimization skipped: {e}") - - return df - - -def arrowTypeFor(dbType: str): - base = dbType.split()[0] - if base in ("float", "double", "decimal"): - return pa.float64() - if base in ("tinyint", "smallint", "mediumint", "int", "bigint"): - return pa.int64() - if base in ("date", "datetime", "timestamp"): - return pa.timestamp("us") - return pa.string() - - -@retry( - stop=stop_after_attempt(3), - wait=wait_exponential(), - retry=retry_if_exception_type(OperationalError), - reraise=True, -) -def buildFeatherCache(engine: Engine | None = None): - sampleCols = None - sampleParts: dict[str, pd.Series] = {} - compressor = zstd.ZstdCompressor(level=3) - - CACHE_FEATHER_PATH.parent.mkdir(parents=True, exist_ok=True) - tmpNested = CACHE_NESTED_PATH.with_suffix(".tmp") - tmpMain = CACHE_FEATHER_PATH.with_suffix(".tmp") - - writer = None - sink = None - schema = None - total = 0 - resolvedEngine = engine if engine is not None else stocksEngine - try: - with resolvedEngine.connect() as conn: - try: - typeRows = conn.exec_driver_sql("SHOW COLUMNS FROM b3_stocks").fetchall() - colTypes = {r[0]: str(r[1]).lower().split("(")[0].strip() for r in typeRows} - except Exception: - colTypes = {} - stream = conn.execution_options(stream_results=True) - result = stream.exec_driver_sql("SELECT * FROM b3_stocks ORDER BY TICKER ASC, TIME DESC") - try: - columns = list(result.keys()) - while True: - batch = result.fetchmany(2000) - if not batch: - break - chunk = pd.DataFrame.from_records((tuple(r) for r in batch), columns=columns) - if sampleCols is None: - sampleCols = [c for c in JSON_COLUMNS if c in chunk.columns] - for col in sampleCols or (): - if col not in sampleParts: - nonNull = chunk[col].dropna() - if not nonNull.empty: - sampleParts[col] = nonNull.head(20).reset_index(drop=True) - chunk[col] = chunk[col].map( - lambda s: compressor.compress(s.encode("utf-8")) if isinstance(s, str) else None - ) - chunk = optimizeDtypes(chunk) - - for col in CATEGORY_COLS: - if col in chunk.columns and str(chunk[col].dtype) == "category": - chunk[col] = chunk[col].astype(str) - if schema is None: - t0 = pa.Table.from_pandas(chunk, preserve_index=False) - fields = [] - for n in t0.column_names: - t = t0.schema.field(n).type - if n in (sampleCols or ()): - fields.append(pa.field(n, pa.binary())) - elif pa.types.is_null(t): - fields.append(pa.field(n, arrowTypeFor(colTypes.get(n, "varchar")))) - else: - fields.append(pa.field(n, t)) - schema = pa.schema(fields).with_metadata({PRESORTED_FLAG_KEY: b"1"}) - sink = pa.OSFile(str(tmpMain), "wb") - writer = pa.ipc.new_file(sink, schema) - assert writer is not None # nosec: B101 mypy narrowing, writer assigned just above - table = pa.Table.from_pandas(chunk, schema=schema, preserve_index=False) - writer.write_table(table) - total += len(chunk) - del chunk, table - finally: - try: - result.close() - except Exception: - pass # nosec: B110 best-effort writer/sink close, retried next refresh - except OperationalError: - logger.warning("feather build lost connection, retrying with fresh connection") - try: - resolvedEngine.dispose() - except Exception: - pass # nosec: B110 dispose is best-effort, original error re-raised below - raise - finally: - if writer is not None: - writer.close() - if sink is not None: - sink.close() - - nestedSample = pd.DataFrame(sampleParts) if sampleParts else None - if nestedSample is not None: - nestedSample.to_feather(tmpNested) - os.replace(tmpNested, CACHE_NESTED_PATH) - if writer is not None: - os.replace(tmpMain, CACHE_FEATHER_PATH) - logger.info(f"feather written to {CACHE_FEATHER_PATH} ({total} records)") - - -def tryBuildLock(): - if fcntl is None: - return open(os.devnull, "w") - lockPath = CACHE_FEATHER_PATH.parent / "refresh.lock" - try: - lockPath.parent.mkdir(parents=True, exist_ok=True) - lockFile = open(lockPath, "w") - except OSError: - return open(os.devnull, "w") - try: - fcntl.flock(lockFile, fcntl.LOCK_EX | fcntl.LOCK_NB) - return lockFile - except OSError: - lockFile.close() - return None - - -def sortCacheFrame(df: pd.DataFrame) -> pd.DataFrame: - if df.empty or "TIME" not in df.columns or "TICKER" not in df.columns: - return df - try: - return df.sort_values(by=["TICKER", "TIME"], ascending=[True, False], kind="mergesort").reset_index(drop=True) - except TypeError: - logger.warning("sortCacheFrame: mixed TIME dtypes, keeping load order") - return df.reset_index(drop=True) - - -def buildTickerIndex(df: pd.DataFrame) -> dict: - index = {} - for idx, ticker in enumerate(df["TICKER"]): - key = str(ticker).upper() - if key not in index: - index[key] = idx - return index - - -def readFeatherDataFrame(path: Path) -> tuple[pd.DataFrame, bool]: - table = feather.read_table(path, memory_map=True) - presorted = (table.schema.metadata or {}).get(PRESORTED_FLAG_KEY) == b"1" - df = table.to_pandas(split_blocks=True, types_mapper=pd.ArrowDtype) - return df, presorted class StocksCacheManager: diff --git a/main/app/stocks_api/frame.py b/main/app/stocks_api/frame.py new file mode 100644 index 00000000..ab40d567 --- /dev/null +++ b/main/app/stocks_api/frame.py @@ -0,0 +1,64 @@ +"""Pure DataFrame helpers for the stocks feather cache (no I/O, no imports +from sibling stocks_api modules other than util — leaf module).""" + +import logging + +import pandas as pd +import pyarrow as pa + +from main.app.stocks_api.util import JSON_COLUMNS + +logger = logging.getLogger(__name__) + +CATEGORY_COLS = frozenset(["TICKER", "NOME"]) +PRESORTED_FLAG_KEY = b"b3_presorted" + + +def optimizeDtypes(df: pd.DataFrame) -> pd.DataFrame: + for col in CATEGORY_COLS: + if col in df.columns: + df[col] = df[col].astype("category") + + for col in df.select_dtypes(include=["float64"]).columns: + df[col] = pd.to_numeric(df[col], downcast="float") + + try: + for col in df.columns: + if str(df[col].dtype) not in ("object", "str"): + continue + if col not in CATEGORY_COLS and col not in JSON_COLUMNS and df[col].notna().all(): + df[col] = df[col].astype("string[pyarrow]") + except Exception as e: + logger.debug(f"Arrow string optimization skipped: {e}") + + return df + + +def arrowTypeFor(dbType: str): + base = dbType.split()[0] + if base in ("float", "double", "decimal"): + return pa.float64() + if base in ("tinyint", "smallint", "mediumint", "int", "bigint"): + return pa.int64() + if base in ("date", "datetime", "timestamp"): + return pa.timestamp("us") + return pa.string() + + +def sortCacheFrame(df: pd.DataFrame) -> pd.DataFrame: + if df.empty or "TIME" not in df.columns or "TICKER" not in df.columns: + return df + try: + return df.sort_values(by=["TICKER", "TIME"], ascending=[True, False], kind="mergesort").reset_index(drop=True) + except TypeError: + logger.warning("sortCacheFrame: mixed TIME dtypes, keeping load order") + return df.reset_index(drop=True) + + +def buildTickerIndex(df: pd.DataFrame) -> dict: + index = {} + for idx, ticker in enumerate(df["TICKER"]): + key = str(ticker).upper() + if key not in index: + index[key] = idx + return index From 896d71d989c9d2168a20fabb6ac907a360bd84c2 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Tue, 29 Sep 2026 21:36:45 -0300 Subject: [PATCH 02/10] break cache-compress cycle with dependency injection --- main/app/stocks_api/compress.py | 79 ++++++++++++++++++------- main/controller/stocksapi_controller.py | 30 ++++++++-- tests/test_stocks_api_cache_ttl.py | 6 +- tests/test_stocks_cache_zstd.py | 10 +--- tests/test_stocks_compress.py | 57 +++++++----------- 5 files changed, 108 insertions(+), 74 deletions(-) diff --git a/main/app/stocks_api/compress.py b/main/app/stocks_api/compress.py index 4d1374b8..199bc302 100644 --- a/main/app/stocks_api/compress.py +++ b/main/app/stocks_api/compress.py @@ -1,10 +1,10 @@ from __future__ import annotations import re -from functools import lru_cache from typing import Any -from main.app.stocks_api import cache +import pandas as pd + from main.app.stocks_api.util import generateAbbreviations, categorizeColumns, detectNestedFields PRICE = { @@ -18,29 +18,56 @@ DF = re.compile(r"^\d{2}-\d{2}-(\d{4})$") DI = re.compile(r"^(\d{4})-\d{2}-\d{2}$") - -@lru_cache(maxsize=1) -def getAbbr() -> dict: - if cache.stocksCache.STOCKS_CACHE is not None: - h, f = categorizeColumns(cache.stocksCache.STOCKS_CACHE.columns.tolist()) - return generateAbbreviations(h, f) - return {"meta": {"TICKER": "TK", "NOME": "NM", "TIME": "TI"}, "historical": {}, "fundamental": {}} - - -@lru_cache(maxsize=1) -def getNest() -> dict: - if cache.stocksCache.STOCKS_CACHE is not None: - nest = detectNestedFields(cache.stocksCache.STOCKS_CACHE) - if cache.stocksCache.nestedSample is not None: - for col, info in detectNestedFields(cache.stocksCache.nestedSample).items(): +ABBR_FALLBACK = {"meta": {"TICKER": "TK", "NOME": "NM", "TIME": "TI"}, "historical": {}, "fundamental": {}} + +_abbrFrame: pd.DataFrame | None = None +_abbrValue: dict | None = None +_nestFrame: pd.DataFrame | None = None +_nestSample: pd.DataFrame | None = None +_nestValue: dict | None = None + + +def getAbbr(df: pd.DataFrame | None = None) -> dict: + """Abbreviation map for a frame (dependency-injected; no cache import). + + Results are memoized by frame identity (strong refs, `is` comparison — + DataFrames are unhashable so lru_cache cannot key on them). Pass None + for the meta-only fallback. Call rebuildAbbrevs() after the feather + frame is replaced, same as before. + """ + global _abbrFrame, _abbrValue + if _abbrValue is not None and _abbrFrame is df: + return _abbrValue + if df is not None: + h, f = categorizeColumns(df.columns.tolist()) + value = generateAbbreviations(h, f) + else: + value = {"meta": dict(ABBR_FALLBACK["meta"]), "historical": {}, "fundamental": {}} + _abbrFrame, _abbrValue = df, value + return value + + +def getNest(df: pd.DataFrame | None = None, nestedSample: pd.DataFrame | None = None) -> dict: + """Nested-field map for a frame plus its nested sample (same memo policy).""" + global _nestFrame, _nestSample, _nestValue + if _nestValue is not None and _nestFrame is df and _nestSample is nestedSample: + return _nestValue + if df is not None: + nest = detectNestedFields(df) + if nestedSample is not None: + for col, info in detectNestedFields(nestedSample).items(): nest.setdefault(col, info) - return nest - return {} + value = nest + else: + value = {} + _nestFrame, _nestSample, _nestValue = df, nestedSample, value + return value def rebuildAbbrevs() -> None: - getAbbr.cache_clear() - getNest.cache_clear() + global _abbrFrame, _abbrValue, _nestFrame, _nestSample, _nestValue + _abbrFrame, _abbrValue = None, None + _nestFrame, _nestSample, _nestValue = None, None, None def compactValue(v: Any) -> Any: @@ -127,7 +154,13 @@ def toCol(cd: list) -> dict: return result -def compressResponse(raw: dict, tool: str, args: dict) -> dict: +def compressResponse( + raw: dict, + tool: str, + args: dict, + df: pd.DataFrame | None = None, + nestedSample: pd.DataFrame | None = None, +) -> dict: result = dict(raw) result.pop("count", None) for k in ("search", "fields", "dates"): @@ -144,7 +177,7 @@ def compressResponse(raw: dict, tool: str, args: dict) -> dict: d = result.get("data") if isinstance(d, list) and d and isinstance(d[0], dict): - abbrs, nests = getAbbr(), getNest() + abbrs, nests = getAbbr(df), getNest(df, nestedSample) result["data"] = [compactRow(row, tool, abbrs, nests) for row in d] def compactLeaves(v: Any) -> Any: diff --git a/main/controller/stocksapi_controller.py b/main/controller/stocksapi_controller.py index 135f48a5..2a83440d 100644 --- a/main/controller/stocksapi_controller.py +++ b/main/controller/stocksapi_controller.py @@ -81,7 +81,7 @@ def listFields(response: Response): cols = stocksCache.STOCKS_CACHE.columns.tolist() historical, fundamental = categorizeColumns(cols) abbreviations = generateAbbreviations(historical, fundamental) - nested = getNest() + nested = getNest(stocksCache.STOCKS_CACHE, stocksCache.nestedSample) response.headers["Cache-Control"] = f"public, max-age={STOCKS_MAX_AGE}" return {"historical": historical, "fundamental": fundamental, "abbreviations": abbreviations, "nested": nested} @@ -148,7 +148,13 @@ def getHistorical( response.headers["Cache-Control"] = f"public, max-age={STOCKS_MAX_AGE}" result = queryHistorical(search, fields, dates, orderBy, limit) if compact: - result = compressResponse(result, "get_historical", {"search": search, "fields": fields, "dates": dates}) + result = compressResponse( + result, + "get_historical", + {"search": search, "fields": fields, "dates": dates}, + stocksCache.STOCKS_CACHE, + stocksCache.nestedSample, + ) return result @@ -218,7 +224,13 @@ def getFundamental( response.headers["Cache-Control"] = f"public, max-age={STOCKS_MAX_AGE}" result = queryFundamental(search, fields, dates, orderBy, limit) if compact: - result = compressResponse(result, "get_fundamental", {"search": search, "fields": fields, "dates": dates}) + result = compressResponse( + result, + "get_fundamental", + {"search": search, "fields": fields, "dates": dates}, + stocksCache.STOCKS_CACHE, + stocksCache.nestedSample, + ) return result @@ -274,7 +286,13 @@ def getCotations( response.headers["Cache-Control"] = f"public, max-age={STOCKS_MAX_AGE}" result = queryCotations(search, dates, adjusted) if compact: - result = compressResponse(result, "get_cotations", {"search": search, "dates": dates}) + result = compressResponse( + result, + "get_cotations", + {"search": search, "dates": dates}, + stocksCache.STOCKS_CACHE, + stocksCache.nestedSample, + ) return result @@ -319,5 +337,7 @@ def getLiveCotation( response.headers["Cache-Control"] = f"public, max-age={LIVE_MAX_AGE}" result = queryLiveCotation(search) if compact: - result = compressResponse(result, "get_live_price", {"search": search}) + result = compressResponse( + result, "get_live_price", {"search": search}, stocksCache.STOCKS_CACHE, stocksCache.nestedSample + ) return result diff --git a/tests/test_stocks_api_cache_ttl.py b/tests/test_stocks_api_cache_ttl.py index 4ad743ab..82509250 100644 --- a/tests/test_stocks_api_cache_ttl.py +++ b/tests/test_stocks_api_cache_ttl.py @@ -60,8 +60,10 @@ def fakeCategorize(cols): monkeypatch.setattr(mod, "categorizeColumns", fakeCategorize) monkeypatch.setattr(mod, "generateAbbreviations", lambda historical, fundamental: {"A": "A"}) - monkeypatch.setattr(mod, "getNest", lambda: {}) - monkeypatch.setattr(mod, "stocksCache", SimpleNamespace(STOCKS_CACHE=pd.DataFrame({"TICKER": ["PETR4"]}))) + monkeypatch.setattr(mod, "getNest", lambda *a: {}) + monkeypatch.setattr( + mod, "stocksCache", SimpleNamespace(STOCKS_CACHE=pd.DataFrame({"TICKER": ["PETR4"]}), nestedSample=None) + ) response = Response() first = mod.listFields(response) diff --git a/tests/test_stocks_cache_zstd.py b/tests/test_stocks_cache_zstd.py index 156f79b5..32adcbe5 100644 --- a/tests/test_stocks_cache_zstd.py +++ b/tests/test_stocks_cache_zstd.py @@ -306,16 +306,10 @@ def test_get_nest_keeps_compressed_column_subfields(monkeypatch, tmp_path): cache_mod.buildFeatherCache() m = StocksCacheManager(None, threading.Lock()) m.getCachedStocks() - from unittest.mock import patch - from main.app.stocks_api.cache import stocksCache from main.app.stocks_api.compress import getNest, rebuildAbbrevs - with ( - patch.object(stocksCache, "STOCKS_CACHE", m.STOCKS_CACHE), - patch.object(stocksCache, "nestedSample", m.nestedSample), - ): - rebuildAbbrevs() - nest = getNest() + rebuildAbbrevs() + nest = getNest(m.STOCKS_CACHE, m.nestedSample) assert "COTACAO 10Y PADRAO" in nest assert set(nest["COTACAO 10Y PADRAO"]["subfields"]) >= {"DATA", "PRECO"} diff --git a/tests/test_stocks_compress.py b/tests/test_stocks_compress.py index 9fe28eb4..e589d8cd 100644 --- a/tests/test_stocks_compress.py +++ b/tests/test_stocks_compress.py @@ -5,18 +5,15 @@ compactCotations, the compressResponse pipeline, and the lazy abbr/nest caches (getAbbr/getNest/rebuildAbbrevs). -Pure unit tests: no MySQL required. Cache-dependent functions are -exercised by patching stocksCache attributes; the module-level -abbr/nest globals are reset before and after every test so the +Pure unit tests: no MySQL required. Cache-dependent functions take +the frame (and nested sample) as injected arguments; the module-level +abbr/nest memos are reset before and after every test so the suite is order-independent. """ -from unittest.mock import patch - import pandas as pd import pytest -from main.app.stocks_api.cache import stocksCache from main.app.stocks_api.compress import ( compactCotations, compactRow, @@ -221,14 +218,12 @@ class TestAbbrevCaches: """getAbbr/getNest/rebuildAbbrevs: fallbacks, cache-present discovery, resets.""" def test_get_abbr_cache_absent_fallback(self): - with patch.object(stocksCache, "STOCKS_CACHE", None): - rebuildAbbrevs() - assert getAbbr() == ABBR_FALLBACK + rebuildAbbrevs() + assert getAbbr(None) == ABBR_FALLBACK def test_get_nest_cache_absent_fallback(self): - with patch.object(stocksCache, "STOCKS_CACHE", None): - rebuildAbbrevs() - assert getNest() == {} + rebuildAbbrevs() + assert getNest(None) == {} def test_get_abbr_cache_present(self): df = pd.DataFrame( @@ -240,9 +235,8 @@ def test_get_abbr_cache_present(self): "P/L": [5.2], } ) - with patch.object(stocksCache, "STOCKS_CACHE", df): - rebuildAbbrevs() - abbr = getAbbr() + rebuildAbbrevs() + abbr = getAbbr(df) assert abbr["meta"] == {"TICKER": "TK", "NOME": "NM", "TIME": "TI"} assert abbr["historical"] == {"LUCRO LIQUIDO": "LL"} assert abbr["fundamental"] == {"P/L": "PL"} @@ -255,12 +249,8 @@ def test_get_nest_cache_present_merges_nested_sample(self): "DIVIDENDOS": ['[{"DATA": "01-01-2024"}]'], } ) - with ( - patch.object(stocksCache, "STOCKS_CACHE", df), - patch.object(stocksCache, "nestedSample", nested), - ): - rebuildAbbrevs() - nest = getNest() + rebuildAbbrevs() + nest = getNest(df, nested) assert set(nest["NOTICIAS"]["subfields"]) >= {"TITULO", "LINK"} assert nest["NOTICIAS"]["dropped_in_compact"] == ["LINK"] assert nest["NOTICIAS"]["max_items_compact"] == 5 @@ -269,19 +259,16 @@ def test_get_nest_cache_present_merges_nested_sample(self): def test_get_abbr_cached_across_calls(self): df = pd.DataFrame({"TICKER": ["X"]}) - with patch.object(stocksCache, "STOCKS_CACHE", df): - rebuildAbbrevs() - assert getAbbr() is getAbbr() + rebuildAbbrevs() + assert getAbbr(df) is getAbbr(df) def test_rebuild_abbrevs_resets_globals(self): df = pd.DataFrame({"TICKER": ["PETR4"], "LUCRO LIQUIDO 2024": [1]}) - with patch.object(stocksCache, "STOCKS_CACHE", df): - rebuildAbbrevs() - assert getAbbr()["historical"] != {} rebuildAbbrevs() - with patch.object(stocksCache, "STOCKS_CACHE", None): - assert getAbbr() == ABBR_FALLBACK - assert getNest() == {} + assert getAbbr(df)["historical"] != {} + rebuildAbbrevs() + assert getAbbr() == ABBR_FALLBACK + assert getNest() == {} class TestCompressResponse: @@ -414,9 +401,8 @@ def test_multi_row_list_of_dicts_with_fallback_abbrs(self): def test_single_row_unwrapped_with_cache_abbrevs(self): df = pd.DataFrame({"TICKER": ["PETR4"], "P/L": [5.2]}) raw = {"data": [{"TICKER": "PETR4", "P/L": 5.2}]} - with patch.object(stocksCache, "STOCKS_CACHE", df): - rebuildAbbrevs() - out = compressResponse(raw, "get_fundamental", {}) + rebuildAbbrevs() + out = compressResponse(raw, "get_fundamental", {}, df) assert out == {"data": {"TK": "PETR4", "PL": 5.2}} def test_get_historical_year_cols_with_cache_abbrevs(self): @@ -444,9 +430,8 @@ def test_get_historical_year_cols_with_cache_abbrevs(self): } ], } - with patch.object(stocksCache, "STOCKS_CACHE", df): - rebuildAbbrevs() - out = compressResponse(raw, "get_historical", {"search": "PETR4", "dates": "2023,2024"}) + rebuildAbbrevs() + out = compressResponse(raw, "get_historical", {"search": "PETR4", "dates": "2023,2024"}, df) # note: leaf compaction suffixes int leaves, so year values become "50K"/"100K"; # the single row is unwrapped from a list but stays under the "data" key assert out == { From 0531c7fd594a883852b5b5d1ff73468aab5dba56 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Tue, 29 Sep 2026 21:49:18 -0300 Subject: [PATCH 03/10] remove cache perf waste and magic values --- main/app/stocks_api/build.py | 17 +++++++++++++---- main/app/stocks_api/cache.py | 3 ++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/main/app/stocks_api/build.py b/main/app/stocks_api/build.py index 57381734..178a2f3d 100644 --- a/main/app/stocks_api/build.py +++ b/main/app/stocks_api/build.py @@ -39,6 +39,10 @@ logger = logging.getLogger(__name__) +FETCHMANY_SIZE = 2000 +ZSTD_LEVEL = 3 +NESTED_SAMPLE_ROWS = 20 + CACHE_FEATHER_PATH = Path("/app/cache/stocks_cache.feather") CACHE_NESTED_PATH = Path("/app/cache/stocks_nested.feather") @@ -63,7 +67,7 @@ def _runtimeConf() -> tuple: def buildFeatherCache(engine: Engine | None = None): sampleCols = None sampleParts: dict[str, pd.Series] = {} - compressor = zstd.ZstdCompressor(level=3) + compressor = zstd.ZstdCompressor(level=ZSTD_LEVEL) defaultEngine, featherPath, nestedPath = _runtimeConf() featherPath.parent.mkdir(parents=True, exist_ok=True) @@ -80,14 +84,15 @@ def buildFeatherCache(engine: Engine | None = None): try: typeRows = conn.exec_driver_sql("SHOW COLUMNS FROM b3_stocks").fetchall() colTypes = {r[0]: str(r[1]).lower().split("(")[0].strip() for r in typeRows} - except Exception: + except Exception as e: + logger.warning(f"SHOW COLUMNS failed, continuing without DB types: {e}") colTypes = {} stream = conn.execution_options(stream_results=True) result = stream.exec_driver_sql("SELECT * FROM b3_stocks ORDER BY TICKER ASC, TIME DESC") try: columns = list(result.keys()) while True: - batch = result.fetchmany(2000) + batch = result.fetchmany(FETCHMANY_SIZE) if not batch: break chunk = pd.DataFrame.from_records((tuple(r) for r in batch), columns=columns) @@ -97,12 +102,16 @@ def buildFeatherCache(engine: Engine | None = None): if col not in sampleParts: nonNull = chunk[col].dropna() if not nonNull.empty: - sampleParts[col] = nonNull.head(20).reset_index(drop=True) + sampleParts[col] = nonNull.head(NESTED_SAMPLE_ROWS).reset_index(drop=True) chunk[col] = chunk[col].map( lambda s: compressor.compress(s.encode("utf-8")) if isinstance(s, str) else None ) chunk = optimizeDtypes(chunk) + # Load-bearing: per-chunk category dictionaries differ across + # batches, and the IPC writer rejects a second dictionary + # for the same field ("Dictionary replacement detected"). + # Casting back to plain str keeps the on-disk schema stable. for col in CATEGORY_COLS: if col in chunk.columns and str(chunk[col].dtype) == "category": chunk[col] = chunk[col].astype(str) diff --git a/main/app/stocks_api/cache.py b/main/app/stocks_api/cache.py index 95f0af98..2ca78c94 100644 --- a/main/app/stocks_api/cache.py +++ b/main/app/stocks_api/cache.py @@ -49,6 +49,7 @@ logger = logging.getLogger(__name__) STALE_AFTER_SECONDS = 6 * 3600 +CACHE_REFRESH_HOURS = 12 CACHE_LOAD_LOCK = threading.Lock() @@ -73,7 +74,7 @@ def cacheScheduler(self): "interval", jobId="stocks_cache_refresh", jobName="Stocks cache refresh", - hours=12, + hours=CACHE_REFRESH_HOURS, ) def loadFromFeather(self): From f1659c41c4ff8da51da656311987925bc6e81a1e Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Tue, 29 Sep 2026 22:43:21 -0300 Subject: [PATCH 04/10] remove deferred config lookup, all-list and import aliases --- main/app/stocks_api/build.py | 47 +++---------- main/app/stocks_api/cache.py | 25 +------ main/app/stocks_api/sync_cache.py | 8 +-- tests/test_stocks_cache_feather.py | 5 +- tests/test_stocks_cache_zstd.py | 106 +++++++++++++++++------------ tests/test_stocks_perf.py | 2 +- 6 files changed, 80 insertions(+), 113 deletions(-) diff --git a/main/app/stocks_api/build.py b/main/app/stocks_api/build.py index 178a2f3d..a58f7028 100644 --- a/main/app/stocks_api/build.py +++ b/main/app/stocks_api/build.py @@ -1,15 +1,3 @@ -"""Feather build / read helpers for the stocks cache. - -Owns the on-disk layout (CACHE_*_PATH) and the DB-to-feather build. -Imports from frame.py only — never from cache.py at module load, so the -load-time graph stays acyclic (cache -> build -> frame). - -Runtime config (engine + paths) is resolved via the cache module at call -time (_runtimeConf): tests rebind stocksEngine / CACHE_*_PATH on -main.app.stocks_api.cache, and reading them there keeps those patch -sites working with zero behavior change in production. -""" - import logging import os import sys @@ -24,7 +12,7 @@ from sqlalchemy.exc import OperationalError from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_exponential -from config import stocksEngine as _fallbackStocksEngine +from config import stocksEngine from main.app.stocks_api.frame import ( CATEGORY_COLS, PRESORTED_FLAG_KEY, @@ -47,17 +35,6 @@ CACHE_NESTED_PATH = Path("/app/cache/stocks_nested.feather") -def _runtimeConf() -> tuple: - """Return (engine, featherPath, nestedPath), preferring live values on - the cache module (where tests monkeypatch) over this module's defaults.""" - import main.app.stocks_api.cache as cacheMod - - engine = getattr(cacheMod, "stocksEngine", None) or _fallbackStocksEngine - featherPath = getattr(cacheMod, "CACHE_FEATHER_PATH", CACHE_FEATHER_PATH) - nestedPath = getattr(cacheMod, "CACHE_NESTED_PATH", CACHE_NESTED_PATH) - return engine, featherPath, nestedPath - - @retry( stop=stop_after_attempt(3), wait=wait_exponential(), @@ -69,16 +46,15 @@ def buildFeatherCache(engine: Engine | None = None): sampleParts: dict[str, pd.Series] = {} compressor = zstd.ZstdCompressor(level=ZSTD_LEVEL) - defaultEngine, featherPath, nestedPath = _runtimeConf() - featherPath.parent.mkdir(parents=True, exist_ok=True) - tmpNested = nestedPath.with_suffix(".tmp") - tmpMain = featherPath.with_suffix(".tmp") + CACHE_FEATHER_PATH.parent.mkdir(parents=True, exist_ok=True) + tmpNested = CACHE_NESTED_PATH.with_suffix(".tmp") + tmpMain = CACHE_FEATHER_PATH.with_suffix(".tmp") writer = None sink = None schema = None total = 0 - resolvedEngine = engine if engine is not None else defaultEngine + resolvedEngine = engine if engine is not None else stocksEngine try: with resolvedEngine.connect() as conn: try: @@ -108,10 +84,6 @@ def buildFeatherCache(engine: Engine | None = None): ) chunk = optimizeDtypes(chunk) - # Load-bearing: per-chunk category dictionaries differ across - # batches, and the IPC writer rejects a second dictionary - # for the same field ("Dictionary replacement detected"). - # Casting back to plain str keeps the on-disk schema stable. for col in CATEGORY_COLS: if col in chunk.columns and str(chunk[col].dtype) == "category": chunk[col] = chunk[col].astype(str) @@ -155,17 +127,16 @@ def buildFeatherCache(engine: Engine | None = None): nestedSample = pd.DataFrame(sampleParts) if sampleParts else None if nestedSample is not None: nestedSample.to_feather(tmpNested) - os.replace(tmpNested, nestedPath) + os.replace(tmpNested, CACHE_NESTED_PATH) if writer is not None: - os.replace(tmpMain, featherPath) - logger.info(f"feather written to {featherPath} ({total} records)") + os.replace(tmpMain, CACHE_FEATHER_PATH) + logger.info(f"feather written to {CACHE_FEATHER_PATH} ({total} records)") def tryBuildLock(): if fcntl is None: return open(os.devnull, "w") - _, featherPath, _ = _runtimeConf() - lockPath = featherPath.parent / "refresh.lock" + lockPath = CACHE_FEATHER_PATH.parent / "refresh.lock" try: lockPath.parent.mkdir(parents=True, exist_ok=True) lockFile = open(lockPath, "w") diff --git a/main/app/stocks_api/cache.py b/main/app/stocks_api/cache.py index 2ca78c94..d5d343a6 100644 --- a/main/app/stocks_api/cache.py +++ b/main/app/stocks_api/cache.py @@ -14,38 +14,15 @@ from main.app.stocks_api.build import ( CACHE_FEATHER_PATH, CACHE_NESTED_PATH, - buildFeatherCache, readFeatherDataFrame, tryBuildLock, ) from main.app.stocks_api.frame import ( - CATEGORY_COLS, - PRESORTED_FLAG_KEY, - arrowTypeFor, buildTickerIndex, - optimizeDtypes, sortCacheFrame, ) from main.utils.scheduler import registerJob -__all__ = [ - "CACHE_FEATHER_PATH", - "CACHE_LOAD_LOCK", - "CACHE_NESTED_PATH", - "CATEGORY_COLS", - "PRESORTED_FLAG_KEY", - "STALE_AFTER_SECONDS", - "StocksCacheManager", - "arrowTypeFor", - "buildFeatherCache", - "buildTickerIndex", - "optimizeDtypes", - "readFeatherDataFrame", - "sortCacheFrame", - "stocksCache", - "tryBuildLock", -] - logger = logging.getLogger(__name__) STALE_AFTER_SECONDS = 6 * 3600 @@ -123,7 +100,7 @@ def getCachedStocks(self, force_refresh: bool = False): [ sys.executable, "-c", - "from main.app.stocks_api.cache import buildFeatherCache; buildFeatherCache()", + "from main.app.stocks_api.build import buildFeatherCache; buildFeatherCache()", ], check=True, ) # nosec: B603 constant args, no untrusted input diff --git a/main/app/stocks_api/sync_cache.py b/main/app/stocks_api/sync_cache.py index fd7e11fc..57a12015 100644 --- a/main/app/stocks_api/sync_cache.py +++ b/main/app/stocks_api/sync_cache.py @@ -3,7 +3,7 @@ from functools import wraps from typing import Any, Callable, TypeVar -from cashews import cache as cashewsCache +import cashews from cashews.key import get_cache_key MISS = object() @@ -18,13 +18,13 @@ def wrapper(*args: Any, **kwargs: Any) -> Any: cache_key = get_cache_key(func, key, args, kwargs) async def cachedCall() -> Any: - cached = await cashewsCache.get(cache_key, default=MISS) + cached = await cashews.cache.get(cache_key, default=MISS) if cached is not MISS: return cached result = func(*args, **kwargs) if inspect.isawaitable(result): result = await result - await cashewsCache.set(cache_key, result, expire=ttl) + await cashews.cache.set(cache_key, result, expire=ttl) return result return asyncio.run(cachedCall()) @@ -36,4 +36,4 @@ async def cachedCall() -> Any: def clearEndpointCache() -> None: """Drop every cached endpoint body — called when the feather frame is replaced.""" - asyncio.run(cashewsCache.clear()) + asyncio.run(cashews.cache.clear()) diff --git a/tests/test_stocks_cache_feather.py b/tests/test_stocks_cache_feather.py index 755b9aa9..9a31fa0c 100644 --- a/tests/test_stocks_cache_feather.py +++ b/tests/test_stocks_cache_feather.py @@ -6,7 +6,8 @@ import pyarrow as pa from pyarrow import feather -from main.app.stocks_api.cache import StocksCacheManager, optimizeDtypes +from main.app.stocks_api.cache import StocksCacheManager +from main.app.stocks_api.frame import PRESORTED_FLAG_KEY, optimizeDtypes def test_optimize_dtypes_skips_pyarrow_for_compress_cols(): @@ -114,7 +115,7 @@ def test_read_feather_dataframe_detects_presorted_marker(tmp_path): path = tmp_path / "cache.feather" table = pa.Table.from_pandas( pd.DataFrame({"TICKER": ["PETR4"], "TIME": [pd.Timestamp("2024-01-01")]}), preserve_index=False - ).replace_schema_metadata({cache_mod.PRESORTED_FLAG_KEY: b"1"}) + ).replace_schema_metadata({PRESORTED_FLAG_KEY: b"1"}) with pa.OSFile(str(path), "wb") as sink, pa.ipc.new_file(sink, table.schema) as writer: writer.write_table(table) diff --git a/tests/test_stocks_cache_zstd.py b/tests/test_stocks_cache_zstd.py index 32adcbe5..f3e79f3b 100644 --- a/tests/test_stocks_cache_zstd.py +++ b/tests/test_stocks_cache_zstd.py @@ -7,8 +7,10 @@ import pyarrow as pa from pyarrow import feather +import main.app.stocks_api.build as build_mod import main.app.stocks_api.cache as cache_mod from main.app.stocks_api.cache import StocksCacheManager +from main.app.stocks_api.frame import PRESORTED_FLAG_KEY from main.app.stocks_api.query import deserializeJsonColumns, filterCotationColumn @@ -58,7 +60,7 @@ def connect(self): @pytest.fixture(autouse=True) def fakeStocksEngine(monkeypatch): - monkeypatch.setattr(cache_mod, "stocksEngine", FakeEngine()) + monkeypatch.setattr(build_mod, "stocksEngine", FakeEngine()) def test_filter_cotation_column_filters_by_date_without_index(): @@ -83,10 +85,12 @@ def test_get_cached_stocks_does_not_build_date_index(monkeypatch, tmp_path): "COTACAO 10Y PADRAO": ['[{"DATA": "01-01-2024", "PRECO": 1.0}]'], } ) - monkeypatch.setattr(cache_mod.stocksEngine, "connect", lambda: FakeConn([df])) - cache_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" - cache_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" - cache_mod.buildFeatherCache() + monkeypatch.setattr(build_mod.stocksEngine, "connect", lambda: FakeConn([df])) + build_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" + build_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" + cache_mod.CACHE_FEATHER_PATH = build_mod.CACHE_FEATHER_PATH + cache_mod.CACHE_NESTED_PATH = build_mod.CACHE_NESTED_PATH + build_mod.buildFeatherCache() monkeypatch.setattr(cache_mod.subprocess, "run", lambda *a, **k: None) m = StocksCacheManager(None, threading.Lock()) m.getCachedStocks() @@ -102,10 +106,12 @@ def test_get_cached_stocks_skips_build_when_another_process_holds_lock(monkeypat "COTACAO 10Y PADRAO": ['[{"DATA": "01-01-2024", "PRECO": 1.0}]'], } ) - monkeypatch.setattr(cache_mod.stocksEngine, "connect", lambda: FakeConn([df])) - cache_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" - cache_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" - cache_mod.buildFeatherCache() + monkeypatch.setattr(build_mod.stocksEngine, "connect", lambda: FakeConn([df])) + build_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" + build_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" + cache_mod.CACHE_FEATHER_PATH = build_mod.CACHE_FEATHER_PATH + cache_mod.CACHE_NESTED_PATH = build_mod.CACHE_NESTED_PATH + build_mod.buildFeatherCache() lockFile = open(tmp_path / "refresh.lock", "w") fcntl.flock(lockFile, fcntl.LOCK_EX | fcntl.LOCK_NB) @@ -135,10 +141,12 @@ def makeDf(): def test_get_cached_stocks_compresses_jsoncolumns(monkeypatch, tmp_path): - monkeypatch.setattr(cache_mod.stocksEngine, "connect", lambda: FakeConn([makeDf()])) - cache_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" - cache_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" - cache_mod.buildFeatherCache() + monkeypatch.setattr(build_mod.stocksEngine, "connect", lambda: FakeConn([makeDf()])) + build_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" + build_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" + cache_mod.CACHE_FEATHER_PATH = build_mod.CACHE_FEATHER_PATH + cache_mod.CACHE_NESTED_PATH = build_mod.CACHE_NESTED_PATH + build_mod.buildFeatherCache() monkeypatch.setattr(cache_mod.subprocess, "run", lambda *a, **k: None) m = StocksCacheManager(None, threading.Lock()) m.getCachedStocks() @@ -150,10 +158,12 @@ def test_get_cached_stocks_compresses_jsoncolumns(monkeypatch, tmp_path): def test_get_cached_stocks_keeps_raw_nested_sample(monkeypatch, tmp_path): - monkeypatch.setattr(cache_mod.stocksEngine, "connect", lambda: FakeConn([makeDf()])) - cache_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" - cache_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" - cache_mod.buildFeatherCache() + monkeypatch.setattr(build_mod.stocksEngine, "connect", lambda: FakeConn([makeDf()])) + build_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" + build_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" + cache_mod.CACHE_FEATHER_PATH = build_mod.CACHE_FEATHER_PATH + cache_mod.CACHE_NESTED_PATH = build_mod.CACHE_NESTED_PATH + build_mod.buildFeatherCache() nested = pd.read_feather(cache_mod.CACHE_NESTED_PATH) assert nested is not None assert isinstance(nested["COTACAO 10Y PADRAO"].iloc[0], str) @@ -170,10 +180,12 @@ def test_nested_sample_skips_all_null_leading_rows(monkeypatch, tmp_path): "NOTICIAS": [None, None], } ) - monkeypatch.setattr(cache_mod.stocksEngine, "connect", lambda: FakeConn([empty, makeDf()])) - cache_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" - cache_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" - cache_mod.buildFeatherCache() + monkeypatch.setattr(build_mod.stocksEngine, "connect", lambda: FakeConn([empty, makeDf()])) + build_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" + build_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" + cache_mod.CACHE_FEATHER_PATH = build_mod.CACHE_FEATHER_PATH + cache_mod.CACHE_NESTED_PATH = build_mod.CACHE_NESTED_PATH + build_mod.buildFeatherCache() nested = pd.read_feather(cache_mod.CACHE_NESTED_PATH) assert nested is not None assert isinstance(nested["COTACAO 10Y PADRAO"].iloc[0], str) @@ -200,10 +212,12 @@ def test_nested_sample_captures_sparsecolumns_across_chunks(monkeypatch, tmp_pat "NOTICIAS": ['[{"TITULO": "noticia", "LINK": "http://x"}]'], } ) - monkeypatch.setattr(cache_mod.stocksEngine, "connect", lambda: FakeConn([first, later])) - cache_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" - cache_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" - cache_mod.buildFeatherCache() + monkeypatch.setattr(build_mod.stocksEngine, "connect", lambda: FakeConn([first, later])) + build_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" + build_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" + cache_mod.CACHE_FEATHER_PATH = build_mod.CACHE_FEATHER_PATH + cache_mod.CACHE_NESTED_PATH = build_mod.CACHE_NESTED_PATH + build_mod.buildFeatherCache() nested = pd.read_feather(cache_mod.CACHE_NESTED_PATH) assert nested is not None assert isinstance(nested["COTACAO 10Y PADRAO"].iloc[0], str) @@ -233,10 +247,12 @@ def test_build_null_first_chunk_numeric_column_uses_db_type(monkeypatch, tmp_pat } ) conn = FakeConn([first, later], col_types={"DIVIDENDOS 2027": "double"}) - monkeypatch.setattr(cache_mod.stocksEngine, "connect", lambda: conn) - cache_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" - cache_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" - cache_mod.buildFeatherCache() + monkeypatch.setattr(build_mod.stocksEngine, "connect", lambda: conn) + build_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" + build_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" + cache_mod.CACHE_FEATHER_PATH = build_mod.CACHE_FEATHER_PATH + cache_mod.CACHE_NESTED_PATH = build_mod.CACHE_NESTED_PATH + build_mod.buildFeatherCache() df = pd.read_feather(cache_mod.CACHE_FEATHER_PATH) assert df["DIVIDENDOS 2027"].iloc[2] == 1.25 assert str(df["DIVIDENDOS 2027"].dtype).startswith("float") @@ -300,10 +316,12 @@ def test_get_nest_keeps_compressed_column_subfields(monkeypatch, tmp_path): "COTACAO 10Y PADRAO": ['[{"DATA": "01-01-2024", "PRECO": 1.0}]'], } ) - monkeypatch.setattr(cache_mod.stocksEngine, "connect", lambda: FakeConn([df])) - cache_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" - cache_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" - cache_mod.buildFeatherCache() + monkeypatch.setattr(build_mod.stocksEngine, "connect", lambda: FakeConn([df])) + build_mod.CACHE_FEATHER_PATH = tmp_path / "cache.feather" + build_mod.CACHE_NESTED_PATH = tmp_path / "nested.feather" + cache_mod.CACHE_FEATHER_PATH = build_mod.CACHE_FEATHER_PATH + cache_mod.CACHE_NESTED_PATH = build_mod.CACHE_NESTED_PATH + build_mod.buildFeatherCache() m = StocksCacheManager(None, threading.Lock()) m.getCachedStocks() from main.app.stocks_api.compress import getNest, rebuildAbbrevs @@ -328,24 +346,24 @@ def exec_driver_sql(sql): monkeypatch.setattr(conn, "exec_driver_sql", exec_driver_sql) return conn - monkeypatch.setattr(cache_mod.stocksEngine, "connect", connect) - monkeypatch.setattr(cache_mod, "CACHE_FEATHER_PATH", tmp_path / "cache.feather") - monkeypatch.setattr(cache_mod, "CACHE_NESTED_PATH", tmp_path / "nested.feather") + monkeypatch.setattr(build_mod.stocksEngine, "connect", connect) + monkeypatch.setattr(build_mod, "CACHE_FEATHER_PATH", tmp_path / "cache.feather") + monkeypatch.setattr(build_mod, "CACHE_NESTED_PATH", tmp_path / "nested.feather") - cache_mod.buildFeatherCache() + build_mod.buildFeatherCache() assert any("ORDER BY TICKER ASC, TIME DESC" in sql for sql in seenSql) def test_build_stamps_presorted_marker(monkeypatch, tmp_path): - monkeypatch.setattr(cache_mod.stocksEngine, "connect", lambda: FakeConn([makeDf()])) - monkeypatch.setattr(cache_mod, "CACHE_FEATHER_PATH", tmp_path / "cache.feather") - monkeypatch.setattr(cache_mod, "CACHE_NESTED_PATH", tmp_path / "nested.feather") + monkeypatch.setattr(build_mod.stocksEngine, "connect", lambda: FakeConn([makeDf()])) + monkeypatch.setattr(build_mod, "CACHE_FEATHER_PATH", tmp_path / "cache.feather") + monkeypatch.setattr(build_mod, "CACHE_NESTED_PATH", tmp_path / "nested.feather") - cache_mod.buildFeatherCache() + build_mod.buildFeatherCache() - table = feather.read_table(cache_mod.CACHE_FEATHER_PATH) - assert (table.schema.metadata or {}).get(cache_mod.PRESORTED_FLAG_KEY) == b"1" + table = feather.read_table(build_mod.CACHE_FEATHER_PATH) + assert (table.schema.metadata or {}).get(PRESORTED_FLAG_KEY) == b"1" def _writeFeather(rows, path): @@ -363,7 +381,7 @@ def test_load_skips_sort_for_presorted_files(monkeypatch, tmp_path): path = tmp_path / "cache.feather" table = pa.Table.from_pandas( pd.DataFrame({"TICKER": ["VALE3", "PETR4"], "TIME": [pd.Timestamp("2024-01-01")] * 2}), preserve_index=False - ).replace_schema_metadata({cache_mod.PRESORTED_FLAG_KEY: b"1"}) + ).replace_schema_metadata({PRESORTED_FLAG_KEY: b"1"}) with pa.OSFile(str(path), "wb") as sink, pa.ipc.new_file(sink, table.schema) as writer: writer.write_table(table) diff --git a/tests/test_stocks_perf.py b/tests/test_stocks_perf.py index 8d09dacd..52cf09c4 100644 --- a/tests/test_stocks_perf.py +++ b/tests/test_stocks_perf.py @@ -13,7 +13,7 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) from main.app.stocks_api.query import filterCotationColumn -from main.app.stocks_api.cache import optimizeDtypes +from main.app.stocks_api.frame import optimizeDtypes # ── filterCotationColumn without date index ───────────────────────────── From aa286d87d75d6f4e62db7715191533c2327f0ee3 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Tue, 29 Sep 2026 23:46:46 -0300 Subject: [PATCH 05/10] require plain names for module state --- AGENTS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index a8d946ea..272bb66e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -44,6 +44,9 @@ Exit code: 0 = all passed, 1 = at least one failed. Bandit failures are non-bloc - **DB**: Two MySQL connections (`engine` for user_db, `stocksEngine` for stocks_db) - **Entry**: `run.py`, source in `main/` +## Code Style +- Module-level variables use plain names (`abbrFrame`), never a leading-underscore prefix (`_abbrFrame`). + ## Testing - Tests in `tests/test_*.py`, use fixtures from `conftest.py` - Requires MySQL running From c2b907766a7ef354e5c41a1ea1bebd8d5c3b601c Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 00:53:37 -0300 Subject: [PATCH 06/10] use descriptive variable names --- AGENTS.md | 1 + main/app/stocks_api/query.py | 50 ++++++++++++++++++------------------ main/app/stocks_api/util.py | 34 ++++++++++++------------ 3 files changed, 44 insertions(+), 41 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 272bb66e..29315dfd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -46,6 +46,7 @@ Exit code: 0 = all passed, 1 = at least one failed. Bandit failures are non-bloc ## Code Style - Module-level variables use plain names (`abbrFrame`), never a leading-underscore prefix (`_abbrFrame`). +- Use descriptive variable names; no single- or dual-letter names (the only exception is `df` for DataFrames). ## Testing - Tests in `tests/test_*.py`, use fixtures from `conftest.py` diff --git a/main/app/stocks_api/query.py b/main/app/stocks_api/query.py index f351dbdd..3bdadbf3 100644 --- a/main/app/stocks_api/query.py +++ b/main/app/stocks_api/query.py @@ -20,7 +20,7 @@ def sanitizeNanValues(obj): if isinstance(obj, float) and (math.isnan(obj) or math.isinf(obj)): return None if isinstance(obj, dict): - return {k: sanitizeNanValues(v) for k, v in obj.items()} + return {key: sanitizeNanValues(value) for key, value in obj.items()} if isinstance(obj, list): return [sanitizeNanValues(item) for item in obj] if isinstance(obj, pd.Timestamp): @@ -53,13 +53,13 @@ def filterCotationColumn(series: pd.Series, startDate, endDate) -> pd.Series: def baseFrame(cacheManager=None): - cm = cacheManager if cacheManager is not None else stocksCache - snap = getattr(cm, "snapshot", None) + manager = cacheManager if cacheManager is not None else stocksCache + snap = getattr(manager, "snapshot", None) pair = snap() if callable(snap) else None if isinstance(pair, tuple): df, tickerIndex = pair else: - df, tickerIndex = cm.STOCKS_CACHE, cm.tickerIndex + df, tickerIndex = manager.STOCKS_CACHE, manager.tickerIndex if df is None: raise HTTPException(status_code=503, detail="Cache not initialized") return df, tickerIndex @@ -68,8 +68,8 @@ def baseFrame(cacheManager=None): def validateFields(requested: str | None, available: list, typeName: str) -> list: if not requested: return list(available) - wanted = [f.strip() for f in requested.split(",") if f.strip()] - invalid = [f for f in wanted if f not in available] + wanted = [field.strip() for field in requested.split(",") if field.strip()] + invalid = [field for field in wanted if field not in available] if invalid: raise HTTPException( status_code=400, @@ -109,7 +109,7 @@ def finalize( if limit: df = df.head(limit) if cols is not None: - df = df[[c for c in cols if c in df.columns]] + df = df[[column for column in cols if column in df.columns]] if dedupTickers: df = df.drop_duplicates(subset=["TICKER"], keep="first") df = deserializeJsonColumns(df) @@ -128,13 +128,13 @@ def deserializeJsonColumns(df: pd.DataFrame) -> pd.DataFrame: df = df.copy() - def parseJSON(x, decompressor): - if isinstance(x, bytes): - x = decompressor.decompress(x).decode("utf-8") + def parseJSON(cell, decompressor): + if isinstance(cell, bytes): + cell = decompressor.decompress(cell).decode("utf-8") try: - return orjson.loads(x) + return orjson.loads(cell) except (ValueError, TypeError): - return x + return cell decompressor = zstd.ZstdDecompressor() for col in df.columns: @@ -143,10 +143,10 @@ def parseJSON(x, decompressor): dtype == "object" or pd.api.types.is_string_dtype(dtype) or isinstance(dtype, pd.ArrowDtype) ): df[col] = df[col].apply( - lambda x: ( - sanitizeNanValues(parseJSON(x, decompressor)) - if (isinstance(x, str) and x.startswith(("{", "["))) or isinstance(x, bytes) - else sanitizeNanValues(x) + lambda cell: ( + sanitizeNanValues(parseJSON(cell, decompressor)) + if (isinstance(cell, str) and cell.startswith(("{", "["))) or isinstance(cell, bytes) + else sanitizeNanValues(cell) ) ) @@ -157,14 +157,14 @@ def filterBySearchTerms(df: pd.DataFrame, search: str, index: dict | None = None if not search: return df - searchTerms = [s.strip().upper() for s in search.split(",") if s.strip()] + searchTerms = [term.strip().upper() for term in search.split(",") if term.strip()] if not searchTerms: return df lookup = index if index is not None else stocksCache.tickerIndex upperTickers = df["TICKER"].str.upper() - exactSet = {t for t in searchTerms if lookup and t in lookup} - prefixTerms = tuple(t for t in searchTerms if t not in exactSet) + exactSet = {term for term in searchTerms if lookup and term in lookup} + prefixTerms = tuple(term for term in searchTerms if term not in exactSet) exactMask = upperTickers.isin(exactSet) if prefixTerms: return df[exactMask | upperTickers.str.startswith(prefixTerms)] @@ -186,7 +186,7 @@ def queryHistorical( try: availableColumns = df.columns.tolist() availableColumnsSet = set(availableColumns) - historicalFields, _ = categorizeColumns(availableColumns) + historicalFields, ignored = categorizeColumns(availableColumns) if not historicalFields: raise HTTPException(status_code=400, detail="No historical data available in cache") @@ -243,16 +243,16 @@ def queryFundamental( try: availableColumns = df.columns.tolist() availableColumnsSet = set(availableColumns) - _, fundamentalCols = categorizeColumns(availableColumns) + ignored, fundamentalCols = categorizeColumns(availableColumns) fundamentalColsFiltered = [ - c for c in fundamentalCols if c not in ("COTACAO 10Y PADRAO", "COTACAO 10Y AJUSTADA") + column for column in fundamentalCols if column not in ("COTACAO 10Y PADRAO", "COTACAO 10Y AJUSTADA") ] fieldList = ( [ - f - for f in validateFields(fields, fundamentalCols, "fundamental") - if f not in ("COTACAO 10Y PADRAO", "COTACAO 10Y AJUSTADA") + field + for field in validateFields(fields, fundamentalCols, "fundamental") + if field not in ("COTACAO 10Y PADRAO", "COTACAO 10Y AJUSTADA") ] if fields else fundamentalColsFiltered diff --git a/main/app/stocks_api/util.py b/main/app/stocks_api/util.py index 77c55280..a1d7c95f 100644 --- a/main/app/stocks_api/util.py +++ b/main/app/stocks_api/util.py @@ -15,10 +15,10 @@ def dedupAbbrev(used: set, abbrev: str) -> str: - base, n = abbrev, 2 + base, counter = abbrev, 2 while abbrev in used: - abbrev = f"{base}{n}" - n += 1 + abbrev = f"{base}{counter}" + counter += 1 used.add(abbrev) return abbrev @@ -28,19 +28,21 @@ def autoAbbreviate(name: str) -> str: if len(name) <= 3 and " " not in name: return name.replace("/", "") if "/" in name: - parts = [p.strip() for p in name.split("/") if p.strip()] + parts = [part.strip() for part in name.split("/") if part.strip()] if len(parts) <= 2: joined = "".join(parts) if len(joined) <= 5: return joined - return "".join(p[0] for p in parts).upper() + return "".join(part[0] for part in parts).upper() if "." in name: - parts = [p.strip() for p in name.split(".") if p.strip()] + parts = [part.strip() for part in name.split(".") if part.strip()] if len(parts) >= 2: - return "".join(p[0] for p in parts).upper() + return "".join(part[0] for part in parts).upper() words = name.split() if len(words) >= 2: - return "".join(w if w.isdigit() else w[0] for w in words if w.upper() not in PREPOSITIONS).upper() + return "".join( + word if word.isdigit() else word[0] for word in words if word.upper() not in PREPOSITIONS + ).upper() return name[:3].upper() if len(name) > 3 else name.upper() @@ -48,8 +50,8 @@ def generateAbbreviations(historical: dict, fundamental: list) -> dict: used: set[str] = set() return { "meta": {"TICKER": "TK", "NOME": "NM", "TIME": "TI"}, - "historical": {f: dedupAbbrev(used, autoAbbreviate(f)) for f in historical}, - "fundamental": {f: dedupAbbrev(used, autoAbbreviate(f)) for f in fundamental}, + "historical": {field: dedupAbbrev(used, autoAbbreviate(field)) for field in historical}, + "fundamental": {field: dedupAbbrev(used, autoAbbreviate(field)) for field in fundamental}, } @@ -75,17 +77,17 @@ def parseDate(dateStr: str, end: bool = False) -> date: if re.match(r"^\d{4}$", dateStr): return date(int(dateStr), 12, 31) if end else date(int(dateStr), 1, 1) if re.match(r"^\d{4}-\d{2}$", dateStr): - y, m = map(int, dateStr.split("-")) + year, month = map(int, dateStr.split("-")) if end: - return date(y, m, calendar.monthrange(y, m)[1]) - return date(y, m, 1) + return date(year, month, calendar.monthrange(year, month)[1]) + return date(year, month, 1) return date.fromisoformat(dateStr) def parseDateRange(dates: str | None) -> tuple[date | None, date | None]: if not dates or not dates.strip(): return None, None - parts = [d.strip() for d in dates.split(",")] + parts = [part.strip() for part in dates.split(",")] if len(parts) == 1: return parseDate(parts[0], end=False), parseDate(parts[0], end=True) if len(parts) == 2: @@ -120,10 +122,10 @@ def detectNestedFields(df: pd.DataFrame) -> dict[str, dict[str, Any]]: continue used: set[str] = set() - subfields = {k: dedupAbbrev(used, autoAbbreviate(k)) for k in keys} + subfields = {key: dedupAbbrev(used, autoAbbreviate(key)) for key in keys} result[col] = { "subfields": subfields, - "dropped_in_compact": [k for k in subfields if any(t in k.lower() for t in URL_HINTS)], + "dropped_in_compact": [key for key in subfields if any(hint in key.lower() for hint in URL_HINTS)], "max_items_compact": 5 if len(keys) <= 4 else 15, } From f0d2771d9570a5764d8be367b07ff685176ae4b6 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 01:08:30 -0300 Subject: [PATCH 07/10] state underscore-to-plain rename rule explicitly --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 29315dfd..0e282f59 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -45,7 +45,7 @@ Exit code: 0 = all passed, 1 = at least one failed. Bandit failures are non-bloc - **Entry**: `run.py`, source in `main/` ## Code Style -- Module-level variables use plain names (`abbrFrame`), never a leading-underscore prefix (`_abbrFrame`). +- Drop the leading underscore from module-level names (`_abbrFrame` → `abbrFrame`). - Use descriptive variable names; no single- or dual-letter names (the only exception is `df` for DataFrames). ## Testing From 4776f45cd1800da26eb300f82d9d65fe3a92d1ad Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 01:13:51 -0300 Subject: [PATCH 08/10] absorb pending stocks_api rewrite --- main/app/stocks_api/build.py | 7 +- main/app/stocks_api/cache.py | 12 +- main/app/stocks_api/compress.py | 175 +++++++++++++++--------------- main/app/stocks_api/frame.py | 3 - main/app/stocks_api/sync_cache.py | 4 +- 5 files changed, 91 insertions(+), 110 deletions(-) diff --git a/main/app/stocks_api/build.py b/main/app/stocks_api/build.py index a58f7028..5b46872d 100644 --- a/main/app/stocks_api/build.py +++ b/main/app/stocks_api/build.py @@ -13,12 +13,7 @@ from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_exponential from config import stocksEngine -from main.app.stocks_api.frame import ( - CATEGORY_COLS, - PRESORTED_FLAG_KEY, - arrowTypeFor, - optimizeDtypes, -) +from main.app.stocks_api.frame import CATEGORY_COLS, PRESORTED_FLAG_KEY, arrowTypeFor, optimizeDtypes from main.app.stocks_api.util import JSON_COLUMNS fcntl: Any = None diff --git a/main/app/stocks_api/cache.py b/main/app/stocks_api/cache.py index d5d343a6..f21599e5 100644 --- a/main/app/stocks_api/cache.py +++ b/main/app/stocks_api/cache.py @@ -25,10 +25,6 @@ logger = logging.getLogger(__name__) -STALE_AFTER_SECONDS = 6 * 3600 -CACHE_REFRESH_HOURS = 12 -CACHE_LOAD_LOCK = threading.Lock() - class StocksCacheManager: def __init__(self, db: Engine, cacheLock: threading.Lock): @@ -51,7 +47,7 @@ def cacheScheduler(self): "interval", jobId="stocks_cache_refresh", jobName="Stocks cache refresh", - hours=CACHE_REFRESH_HOURS, + hours=12, ) def loadFromFeather(self): @@ -79,7 +75,7 @@ def getCachedStocks(self, force_refresh: bool = False): self.loadFromFeather() ageSeconds = time.time() - os.path.getmtime(CACHE_FEATHER_PATH) - if ageSeconds > STALE_AFTER_SECONDS: + if ageSeconds > 6 * 3600: logger.info(f"Feather is {int(ageSeconds // 3600)}h old, refreshing in background") threading.Thread( target=self.getCachedStocks, @@ -89,7 +85,7 @@ def getCachedStocks(self, force_refresh: bool = False): ).start() return - if CACHE_LOAD_LOCK.acquire(blocking=False): + if threading.Lock().acquire(blocking=False): try: lockFile = tryBuildLock() if lockFile is None: @@ -107,7 +103,7 @@ def getCachedStocks(self, force_refresh: bool = False): finally: lockFile.close() finally: - CACHE_LOAD_LOCK.release() + threading.Lock().release() self.loadFromFeather() else: logger.info("Cache load already in progress, skipping") diff --git a/main/app/stocks_api/compress.py b/main/app/stocks_api/compress.py index 199bc302..8987ac88 100644 --- a/main/app/stocks_api/compress.py +++ b/main/app/stocks_api/compress.py @@ -15,43 +15,35 @@ "PRECO MEDIO": "PMD", } SUF = [(1e12, "T"), (1e9, "B"), (1e6, "M"), (1e3, "K")] -DF = re.compile(r"^\d{2}-\d{2}-(\d{4})$") -DI = re.compile(r"^(\d{4})-\d{2}-\d{2}$") +DMY_DATE = re.compile(r"^\d{2}-\d{2}-(\d{4})$") +ISO_DATE = re.compile(r"^(\d{4})-\d{2}-\d{2}$") ABBR_FALLBACK = {"meta": {"TICKER": "TK", "NOME": "NM", "TIME": "TI"}, "historical": {}, "fundamental": {}} -_abbrFrame: pd.DataFrame | None = None -_abbrValue: dict | None = None -_nestFrame: pd.DataFrame | None = None -_nestSample: pd.DataFrame | None = None -_nestValue: dict | None = None +abbrFrame: pd.DataFrame | None = None +abbrValue: dict | None = None +nestFrame: pd.DataFrame | None = None +nestSample: pd.DataFrame | None = None +nestValue: dict | None = None def getAbbr(df: pd.DataFrame | None = None) -> dict: - """Abbreviation map for a frame (dependency-injected; no cache import). - - Results are memoized by frame identity (strong refs, `is` comparison — - DataFrames are unhashable so lru_cache cannot key on them). Pass None - for the meta-only fallback. Call rebuildAbbrevs() after the feather - frame is replaced, same as before. - """ - global _abbrFrame, _abbrValue - if _abbrValue is not None and _abbrFrame is df: - return _abbrValue + global abbrFrame, abbrValue + if abbrValue is not None and abbrFrame is df: + return abbrValue if df is not None: - h, f = categorizeColumns(df.columns.tolist()) - value = generateAbbreviations(h, f) + historical, fundamental = categorizeColumns(df.columns.tolist()) + value = generateAbbreviations(historical, fundamental) else: value = {"meta": dict(ABBR_FALLBACK["meta"]), "historical": {}, "fundamental": {}} - _abbrFrame, _abbrValue = df, value + abbrFrame, abbrValue = df, value return value def getNest(df: pd.DataFrame | None = None, nestedSample: pd.DataFrame | None = None) -> dict: - """Nested-field map for a frame plus its nested sample (same memo policy).""" - global _nestFrame, _nestSample, _nestValue - if _nestValue is not None and _nestFrame is df and _nestSample is nestedSample: - return _nestValue + global nestFrame, nestSample, nestValue + if nestValue is not None and nestFrame is df and nestSample is nestedSample: + return nestValue if df is not None: nest = detectNestedFields(df) if nestedSample is not None: @@ -60,60 +52,62 @@ def getNest(df: pd.DataFrame | None = None, nestedSample: pd.DataFrame | None = value = nest else: value = {} - _nestFrame, _nestSample, _nestValue = df, nestedSample, value + nestFrame, nestSample, nestValue = df, nestedSample, value return value def rebuildAbbrevs() -> None: - global _abbrFrame, _abbrValue, _nestFrame, _nestSample, _nestValue - _abbrFrame, _abbrValue = None, None - _nestFrame, _nestSample, _nestValue = None, None, None - - -def compactValue(v: Any) -> Any: - if isinstance(v, float): - v = float(f"{v:.10g}") - if isinstance(v, int) and not isinstance(v, bool): - for t, s in SUF: - if abs(v) >= t: - q = v / t - v = f"{int(q)}{s}" if q == int(q) else f"{q:.1f}{s}" + global abbrFrame, abbrValue, nestFrame, nestSample, nestValue + abbrFrame, abbrValue = None, None + nestFrame, nestSample, nestValue = None, None, None + + +def compactValue(value: Any) -> Any: + if isinstance(value, float): + value = float(f"{value:.10g}") + if isinstance(value, int) and not isinstance(value, bool): + for threshold, suffix in SUF: + if abs(value) >= threshold: + quotient = value / threshold + value = f"{int(quotient)}{suffix}" if quotient == int(quotient) else f"{quotient:.1f}{suffix}" break - if isinstance(v, str): - m = DF.match(v) - if m: - dd, rest = v.split("-", 1) - return f"{rest.split('-', 1)[0]}-{dd}" - m = DI.match(v) - if m: - p = v.split("-") - return f"{p[1]}-{p[2]}" - return v + if isinstance(value, str): + match = DMY_DATE.match(value) + if match: + day, rest = value.split("-", 1) + return f"{rest.split('-', 1)[0]}-{day}" + match = ISO_DATE.match(value) + if match: + parts = value.split("-") + return f"{parts[1]}-{parts[2]}" + return value def compactRow(row: dict, tool: str, abbrs: dict, nests: dict) -> dict: - m, h, f = abbrs["meta"], abbrs["historical"], abbrs["fundamental"] + meta, historical, fundamental = abbrs["meta"], abbrs["historical"], abbrs["fundamental"] out = {} - for k, v in row.items(): - if k in m: - out[m[k]] = v - elif tool == "get_historical" and " " in k and k[-4:].isdigit(): - base, year = k.rsplit(" ", 1) - a = h.get(base) or "".join(w[0] for w in base.split() if w) - out[f"{a}.{year[-2:]}"] = v - elif k in f: - out[f[k]] = v + for key, value in row.items(): + if key in meta: + out[meta[key]] = value + elif tool == "get_historical" and " " in key and key[-4:].isdigit(): + base, year = key.rsplit(" ", 1) + abbrev = historical.get(base) or "".join(word[0] for word in base.split() if word) + out[f"{abbrev}.{year[-2:]}"] = value + elif key in fundamental: + out[fundamental[key]] = value else: - out[k] = v + out[key] = value for field, spec in nests.items(): if field in out and isinstance(out[field], list): - km = spec["subfields"] - dr = set(spec.get("dropped_in_compact", [])) - mx = spec.get("max_items_compact", 15) + submap = spec["subfields"] + dropped = set(spec.get("dropped_in_compact", [])) + maxItems = spec.get("max_items_compact", 15) out[field] = [ - {km.get(k, k): v for k, v in x.items() if k not in dr} if isinstance(x, dict) else x - for x in out[field][:mx] + {submap.get(key, key): value for key, value in item.items() if key not in dropped} + if isinstance(item, dict) + else item + for item in out[field][:maxItems] ] return out @@ -124,33 +118,33 @@ def compactCotations(result: dict) -> dict: if not isinstance(data, list): return result - def toCol(cd: list) -> dict: + def toCol(entries: list) -> dict: cot = {"DATA": "D", "PRECO": "P"} - first = cd[0] + first = entries[0] if not isinstance(first, dict): - return {"h": "v", "d": ["|".join(str(v) for v in x) for x in cd]} + return {"h": "v", "d": ["|".join(str(value) for value in entry) for entry in entries]} hdrs = list(first.keys()) return { - "h": ",".join(cot.get(h, h) for h in hdrs), - "d": ["|".join(str(compactValue(x.get(h, ""))) for h in hdrs) for x in cd], + "h": ",".join(cot.get(header, header) for header in hdrs), + "d": ["|".join(str(compactValue(entry.get(header, ""))) for header in hdrs) for entry in entries], } if len(data) == 1 and isinstance(data[0], dict): entry = data[0] - ck = next((k for k in entry if k.startswith("COTACAO")), None) - if ck and isinstance(entry[ck], list) and entry[ck]: + cotationKey = next((key for key in entry if key.startswith("COTACAO")), None) + if cotationKey and isinstance(entry[cotationKey], list) and entry[cotationKey]: result["TK"] = entry.get("TICKER", entry.get("TK", "")) result["NM"] = entry.get("NOME", entry.get("NM", "")) result["TI"] = compactValue(entry.get("TIME", entry.get("TI", ""))) - result["C10" if "10Y" in ck else ck[:4]] = toCol(entry[ck]) + result["C10" if "10Y" in cotationKey else cotationKey[:4]] = toCol(entry[cotationKey]) result.pop("data", None) return result - for i, entry in enumerate(data): + for index, entry in enumerate(data): if isinstance(entry, dict): - ck = next((k for k in entry if k.startswith("COTACAO")), None) - if ck and isinstance(entry[ck], list) and entry[ck]: - result["data"][i] = {**entry, ck: toCol(entry[ck])} + cotationKey = next((key for key in entry if key.startswith("COTACAO")), None) + if cotationKey and isinstance(entry[cotationKey], list) and entry[cotationKey]: + result["data"][index] = {**entry, cotationKey: toCol(entry[cotationKey])} return result @@ -163,29 +157,30 @@ def compressResponse( ) -> dict: result = dict(raw) result.pop("count", None) - for k in ("search", "fields", "dates"): - if k in args and k in result: - result.pop(k) + for key in ("search", "fields", "dates"): + if key in args and key in result: + result.pop(key) result.pop("type", None) if tool == "get_cotations": return compactCotations(result) elif tool == "get_live_price" and isinstance(result.get("data"), list): result["data"] = [ - {PRICE.get(k, k): v for k, v in x.items()} if isinstance(x, dict) else x for x in result["data"] + {PRICE.get(key, key): value for key, value in row.items()} if isinstance(row, dict) else row + for row in result["data"] ] - d = result.get("data") - if isinstance(d, list) and d and isinstance(d[0], dict): + rows = result.get("data") + if isinstance(rows, list) and rows and isinstance(rows[0], dict): abbrs, nests = getAbbr(df), getNest(df, nestedSample) - result["data"] = [compactRow(row, tool, abbrs, nests) for row in d] - - def compactLeaves(v: Any) -> Any: - if isinstance(v, dict): - return {k: compactLeaves(x) for k, x in v.items()} - if isinstance(v, list): - return [compactLeaves(x) for x in v] - return compactValue(v) + result["data"] = [compactRow(row, tool, abbrs, nests) for row in rows] + + def compactLeaves(value: Any) -> Any: + if isinstance(value, dict): + return {key: compactLeaves(item) for key, item in value.items()} + if isinstance(value, list): + return [compactLeaves(item) for item in value] + return compactValue(value) result["data"] = compactLeaves(result["data"]) if isinstance(result["data"], list) and len(result["data"]) == 1: diff --git a/main/app/stocks_api/frame.py b/main/app/stocks_api/frame.py index ab40d567..630e8ad6 100644 --- a/main/app/stocks_api/frame.py +++ b/main/app/stocks_api/frame.py @@ -1,6 +1,3 @@ -"""Pure DataFrame helpers for the stocks feather cache (no I/O, no imports -from sibling stocks_api modules other than util — leaf module).""" - import logging import pandas as pd diff --git a/main/app/stocks_api/sync_cache.py b/main/app/stocks_api/sync_cache.py index 57a12015..1c5d4f8c 100644 --- a/main/app/stocks_api/sync_cache.py +++ b/main/app/stocks_api/sync_cache.py @@ -28,12 +28,10 @@ async def cachedCall() -> Any: return result return asyncio.run(cachedCall()) - + return wrapper # type: ignore[return-value] - return decorator def clearEndpointCache() -> None: - """Drop every cached endpoint body — called when the feather frame is replaced.""" asyncio.run(cashews.cache.clear()) From 9cfa467f5e182a4a67ff4017297a51199f520f60 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 01:17:56 -0300 Subject: [PATCH 09/10] restore shared cache lock and staleness export --- main/app/stocks_api/cache.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/main/app/stocks_api/cache.py b/main/app/stocks_api/cache.py index f21599e5..6c9e17b5 100644 --- a/main/app/stocks_api/cache.py +++ b/main/app/stocks_api/cache.py @@ -26,6 +26,11 @@ logger = logging.getLogger(__name__) +STALE_AFTER_SECONDS = 6 * 3600 +CACHE_REFRESH_HOURS = 12 +CACHE_LOAD_LOCK = threading.Lock() + + class StocksCacheManager: def __init__(self, db: Engine, cacheLock: threading.Lock): self.db = db @@ -47,7 +52,7 @@ def cacheScheduler(self): "interval", jobId="stocks_cache_refresh", jobName="Stocks cache refresh", - hours=12, + hours=CACHE_REFRESH_HOURS, ) def loadFromFeather(self): @@ -75,7 +80,7 @@ def getCachedStocks(self, force_refresh: bool = False): self.loadFromFeather() ageSeconds = time.time() - os.path.getmtime(CACHE_FEATHER_PATH) - if ageSeconds > 6 * 3600: + if ageSeconds > STALE_AFTER_SECONDS: logger.info(f"Feather is {int(ageSeconds // 3600)}h old, refreshing in background") threading.Thread( target=self.getCachedStocks, @@ -85,7 +90,7 @@ def getCachedStocks(self, force_refresh: bool = False): ).start() return - if threading.Lock().acquire(blocking=False): + if CACHE_LOAD_LOCK.acquire(blocking=False): try: lockFile = tryBuildLock() if lockFile is None: @@ -103,7 +108,7 @@ def getCachedStocks(self, force_refresh: bool = False): finally: lockFile.close() finally: - threading.Lock().release() + CACHE_LOAD_LOCK.release() self.loadFromFeather() else: logger.info("Cache load already in progress, skipping") From 274f44b282b76dd1ba0e0480cac6b39b13a0f213 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 01:29:03 -0300 Subject: [PATCH 10/10] graphify --- graphify-out/.graphify_labels.json | 6 +- graphify-out/GRAPH_REPORT.md | 352 +++-- graphify-out/graph.json | 2008 +++++++++++++++++----------- graphify-out/manifest.json | 42 +- main/app/scraper_b3/scraper.py | 10 +- 5 files changed, 1428 insertions(+), 990 deletions(-) diff --git a/graphify-out/.graphify_labels.json b/graphify-out/.graphify_labels.json index 6afb4898..cb727242 100644 --- a/graphify-out/.graphify_labels.json +++ b/graphify-out/.graphify_labels.json @@ -612,10 +612,14 @@ "610": "Community 610", "611": "Community 611", "612": "Community 612", + "613": "Community 613", "614": "Community 614", "615": "Community 615", "616": "Community 616", "617": "Community 617", "618": "Community 618", - "619": "Community 619" + "619": "Community 619", + "621": "Community 621", + "623": "Community 623", + "624": "Community 624" } diff --git a/graphify-out/GRAPH_REPORT.md b/graphify-out/GRAPH_REPORT.md index d738e43a..f75b4f62 100644 --- a/graphify-out/GRAPH_REPORT.md +++ b/graphify-out/GRAPH_REPORT.md @@ -1,16 +1,16 @@ -# Graph Report - server (2026-09-29) +# Graph Report - server (2026-09-30) ## Corpus Check -- 135 files · ~103,084 words +- 137 files · ~103,322 words - Verdict: corpus is large enough that graph structure adds value. ## Summary -- 6630 nodes · 8878 edges · 619 communities (386 shown, 233 thin omitted) -- Extraction: 85% EXTRACTED · 15% INFERRED · 0% AMBIGUOUS · INFERRED: 1329 edges (avg confidence: 0.69) +- 6650 nodes · 8904 edges · 623 communities (380 shown, 243 thin omitted) +- Extraction: 85% EXTRACTED · 15% INFERRED · 0% AMBIGUOUS · INFERRED: 1335 edges (avg confidence: 0.69) - Token cost: 0 input · 0 output ## Graph Freshness -- Built from commit: `e7ac7432` +- Built from commit: `9cfa467f` - Run `git rev-parse HEAD` and compare to check if the graph is stale. - Run `graphify update .` after code changes (no API cost). @@ -614,12 +614,16 @@ - [[_COMMUNITY_Community 610|Community 610]] - [[_COMMUNITY_Community 611|Community 611]] - [[_COMMUNITY_Community 612|Community 612]] +- [[_COMMUNITY_Community 613|Community 613]] - [[_COMMUNITY_Community 614|Community 614]] - [[_COMMUNITY_Community 615|Community 615]] - [[_COMMUNITY_Community 616|Community 616]] - [[_COMMUNITY_Community 617|Community 617]] - [[_COMMUNITY_Community 618|Community 618]] - [[_COMMUNITY_Community 619|Community 619]] +- [[_COMMUNITY_Community 621|Community 621]] +- [[_COMMUNITY_Community 623|Community 623]] +- [[_COMMUNITY_Community 624|Community 624]] ## God Nodes (most connected - your core abstractions) 1. `vocab` - 456 edges @@ -640,10 +644,10 @@ main/app/stocks_api/cache.py → tests/test_stocks_api_coverage.py - `StocksCacheManager` --calls--> `test_cache_scheduler_starts_daemon_thread()` [INFERRED] main/app/stocks_api/cache.py → tests/test_stocks_api_coverage.py +- `DiscordHandler` --uses--> `TestSetupLogging` [INFERRED] + main/utils/logging_config.py → tests/test_logging_config_coverage.py - `HarnessState` --uses--> `TestGetState` [INFERRED] main/app/prometheus/state.py → tests/test_state_tools.py -- `HarnessState` --uses--> `TestSetState` [INFERRED] - main/app/prometheus/state.py → tests/test_state_tools.py ## Hyperedges (group relationships) - **Authentication Module** — AuthenticationManager, SessionManager, auth_util, auth_constants, getGoogleSSO [INFERRED] @@ -653,7 +657,7 @@ - **Configuration & Database Infrastructure** — config_Config, config_engine, config_stocksEngine [INFERRED] - **User Authentication & Authorization** — user_service, authentication, user_roles, permission_system [INFERRED] -## Communities (619 total, 233 thin omitted) +## Communities (623 total, 243 thin omitted) ### Community 0 - "Stocks API Endpoints" Cohesion: 0.0 @@ -688,8 +692,8 @@ Cohesion: 0.07 Nodes (29): Algorithmic Compression (`compact.py`) Implementation Plan, code:python (# main/app/prometheus/compact.py), code:python (# Before:), code:python (# Before:), code:python (# Before:), code:bash (pytest tests/ -k "prometheus" -v), code:bash (git add main/app/prometheus/agent.py), code:bash (git mv main/app/prometheus/summarizer.py main/app/prometheus) (+21 more) ### Community 8 - "Device Detection" -Cohesion: 0.06 -Nodes (15): HarnessState, Retrieve a value from state. Returns default if key not found., Return a copy of the current state., Format state as a string for injection into the LLM context., Check if state changed since last reset., Reset the changed flag. Returns the previous state., Clear all state data., In-memory state dict that persists across loop iterations within a single reques (+7 more) +Cohesion: 0.08 +Nodes (9): HarnessState, Retrieve a value from state. Returns default if key not found., Return a copy of the current state., Format state as a string for injection into the LLM context., Check if state changed since last reset., Reset the changed flag. Returns the previous state., Clear all state data., In-memory state dict that persists across loop iterations within a single reques (+1 more) ### Community 9 - "Server Configuration" Cohesion: 0.11 @@ -712,8 +716,8 @@ Cohesion: 0.06 Nodes (31): code:python ("""Measure whether the stocks query hot path is GIL-bound.), code:bash (git add main/utils/migrator.py tests/test_migrator_guard.py), code:python (import importlib), code:python (DB_POOL_SIZE = int(os.getenv("DB_POOL_SIZE", "20"))), code:bash (git add config.py tests/test_config_pools.py), code:python (import importlib), code:python (if __name__ == "__main__":), code:python (if len(instances) > 1 and fcntl is None: # pragma: no cover) (+23 more) ### Community 14 - "User Roles & Permissions" -Cohesion: 0.06 -Nodes (28): _make_stocksapi_client(), Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental. (+20 more) +Cohesion: 0.05 +Nodes (35): _make_stocksapi_client(), Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental. (+27 more) ### Community 15 - "Community 15" Cohesion: 0.05 @@ -740,8 +744,8 @@ Cohesion: 0.06 Nodes (35): 1. Memory System (B+), 2. Summarizer/Episodes (B), 3. Loop Events (A-), 4. Core Architecture (B+), 5. Security (B+), 6. Performance (B), 7. Code Quality (B), After (B+) (+27 more) ### Community 21 - "Community 21" -Cohesion: 0.14 -Nodes (3): getCurrentSelic(), getInitialData(), calculateInvestingScore() +Cohesion: 0.1 +Nodes (9): B3Scraper, getCurrentSelic(), getInitialData(), calculateInvestingScore(), initialize(), P5: register the scraper cron jobs on the shared scheduler. Kept in this, registerScraperJobs(), runScraper() (+1 more) ### Community 22 - "Community 22" Cohesion: 0.14 @@ -756,16 +760,16 @@ Cohesion: 0.09 Nodes (5): Tests for agent <-> persistent sandbox integration (Task 3)., Verify the agent uses getOrCreate + syncToSandbox/syncFromSandbox., Test the premium gating logic used in streamMessage., TestPersistentSandboxLifecycle, TestPremiumCheck ### Community 25 - "Community 25" -Cohesion: 0.06 -Nodes (13): Tests for input validation via HTTP endpoints. Validation is now inline via Bod, PUT /prometheus/sessions/{sessionId} — validates title via Body(...), POST /prometheus/chat/stream — validates query via Body(...), POST /auth/register — validates username, email, password via Body(...), Test that endpoints reject requests with missing required fields., POST /auth/login — validates username, password via Body(...), POST /prometheus/sessions — validates title via Body(...), TestChatValidation (+5 more) +Cohesion: 0.12 +Nodes (7): Tests for input validation via HTTP endpoints. Validation is now inline via Bod, PUT /prometheus/sessions/{sessionId} — validates title via Body(...), Test that endpoints reject requests with missing required fields., POST /prometheus/sessions — validates title via Body(...), TestMissingBody, TestPrometheusSessionValidation, TestUpdateTitleValidation ### Community 26 - "Community 26" -Cohesion: 0.12 -Nodes (20): createKey(), _hash_key(), hashKey(), Return SHA-256 hex digest of the given key., Test that concurrent requests are properly serialized at DB level. Th, Test edge case: request exactly at quota limit., Test edge case: request exactly at quota limit., Test that increment works from zero usage. (+12 more) +Cohesion: 0.11 +Nodes (21): generateKey(), createKey(), _hash_key(), hashKey(), Return SHA-256 hex digest of the given key., Test that concurrent requests are properly serialized at DB level. Th, Test edge case: request exactly at quota limit., Test edge case: request exactly at quota limit. (+13 more) ### Community 27 - "Community 27" -Cohesion: 0.15 -Nodes (15): getUserMemories(), getRelevanceScore(), _FakeMemory, A memory with no lastAccessedAt should use baseScore as-is., Scores are deterministic — no cron mutation needed., Same memory at different points in time yields different scores., A memory accessed 10x (baseScore 1.0) should still outrank a memory acce, A rarely-used old memory should lose to a popular fresh one. (+7 more) +Cohesion: 0.16 +Nodes (14): getRelevanceScore(), _FakeMemory, A memory with no lastAccessedAt should use baseScore as-is., Scores are deterministic — no cron mutation needed., Same memory at different points in time yields different scores., A memory accessed 10x (baseScore 1.0) should still outrank a memory acce, A rarely-used old memory should lose to a popular fresh one., With same access time, higher baseScore always wins. (+6 more) ### Community 28 - "Community 28" Cohesion: 0.05 @@ -789,7 +793,7 @@ Nodes (12): ToolContext — bundles all dependencies for tool execution. Replac ### Community 33 - "Community 33" Cohesion: 0.12 -Nodes (14): BaseHTTPMiddleware, app(), Tests for standardized error responses (errors.py)., SampleBody, TestErrorResponseModel, TestGenericExceptionHandler, TestHTTPExceptionHandler, TestRequestContextFilter (+6 more) +Nodes (13): BaseHTTPMiddleware, Tests for standardized error responses (errors.py)., SampleBody, TestErrorResponseModel, TestGenericExceptionHandler, TestHTTPExceptionHandler, TestRequestContextFilter, TestSuccessPassthrough (+5 more) ### Community 34 - "Community 34" Cohesion: 0.11 @@ -836,8 +840,8 @@ Cohesion: 0.14 Nodes (3): UserSession, TestSessionExpiration, TestUserSessionModel ### Community 45 - "Community 45" -Cohesion: 0.06 -Nodes (29): Covers line 16: empty password raises ValueError., Covers line 16: empty password raises ValueError., Covers line 16: empty password raises ValueError., Covers line 16: empty password raises ValueError., Covers line 16: empty password raises ValueError., Covers line 13: UserManager.__init__., Covers line 13: UserManager.__init__., Covers line 13: UserManager.__init__. (+21 more) +Cohesion: 0.05 +Nodes (58): BaseModel, IntFlag, OrunmilaMemory, Orunmila, OrunmilaChatManager, MemoryCandidate, OrunmilaMemory, SandboxManager (+50 more) ### Community 46 - "Community 46" Cohesion: 0.09 @@ -868,12 +872,12 @@ Cohesion: 0.08 Nodes (7): Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., TestPrometheusChatManager ### Community 53 - "Community 53" -Cohesion: 0.1 -Nodes (39): applyUpdate(), archiveDead(), clearAll(), clearAllAsync(), count_memories(), countMemories(), countTokensCached(), decayScores() (+31 more) +Cohesion: 0.11 +Nodes (29): charCount(), countTokens(), getTokenizer(), applyUpdate(), archiveDead(), clearAll(), clearAllAsync(), count_memories() (+21 more) ### Community 54 - "Community 54" -Cohesion: 0.33 -Nodes (10): compactCotations(), compactRow(), compactValue(), compressResponse(), fixHeaders(), getAbbr(), getNest(), rebuildAbbrevs() (+2 more) +Cohesion: 0.38 +Nodes (9): compactCotations(), compactRow(), compactValue(), compressResponse(), fixHeaders(), getAbbr(), getNest(), toColumnar() (+1 more) ### Community 55 - "Community 55" Cohesion: 0.11 @@ -908,8 +912,8 @@ Cohesion: 0.1 Nodes (20): architectures, attention_probs_dropout_prob, gradient_checkpointing, hidden_act, hidden_dropout_prob, hidden_size, initializer_range, intermediate_size (+12 more) ### Community 63 - "Community 63" -Cohesion: 0.24 -Nodes (5): Store a value in state. Marks state as changed for context injection., Shared query pipeline for historical and fundamental endpoints., Fetch live prices for B3 tickers via yfinance. B3 tickers must match, sanitizeNanValues(), StocksQueryManager +Cohesion: 0.21 +Nodes (6): normalizeKey(), Store a value in state. Marks state as changed for context injection., Shared query pipeline for historical and fundamental endpoints., Fetch live prices for B3 tickers via yfinance. B3 tickers must match, sanitizeNanValues(), StocksQueryManager ### Community 64 - "Community 64" Cohesion: 0.06 @@ -924,8 +928,8 @@ Cohesion: 0.1 Nodes (19): 1. Explore Agent — Prometheus Architecture, 2. MySQL Vector Storage (Researcher), 3. Memory Patterns (Researcher), A. Vector Embedding Integration, B. Pandas-First Vector Cache, C. Search Upgrade, code:python (class MemoryCache:), code:python (def searchMemories(cls, db, userId, query, embedding=None, l) (+11 more) ### Community 67 - "Community 67" -Cohesion: 0.08 -Nodes (11): Verify memory endpoints exist and are wired correctly., GET /prometheus/memories exists., POST /memories rejects missing key., POST /memories rejects missing value., POST /prometheus/memories exists., DELETE /prometheus/memories/{id} exists., GET /memories requires authentication., GET /memories requires USE_PROMETHEUS (basic USER role denied). (+3 more) +Cohesion: 0.17 +Nodes (7): Verify memory endpoints exist and are wired correctly., GET /prometheus/memories exists., POST /prometheus/memories exists., DELETE /prometheus/memories/{id} exists., GET /memories requires authentication., GET /memories requires USE_PROMETHEUS (basic USER role denied)., TestMemoryControllerRoutes ### Community 68 - "Community 68" Cohesion: 0.23 @@ -944,12 +948,12 @@ Cohesion: 0.11 Nodes (19): API Key System, B3 Scraper, Fundamental Data, Gemini Model, Historical Data, Ma'at Stock Algorithm, Mansa Server, MySQL Database (+11 more) ### Community 72 - "Community 72" -Cohesion: 0.19 -Nodes (9): initialize(), P5: register the session-cleanup job on the shared scheduler. Kept in thi, registerSessionCleanupJobs(), UserService, getSharedScheduler(), P5: single shared BackgroundScheduler for all services. Replaces the 4 per-serv, Return the process-wide scheduler, starting it on first use., Register func on the shared scheduler (replaces any same-id job). trigger i (+1 more) +Cohesion: 0.13 +Nodes (16): pack → unpack preserves values., Empty list roundtrips., 384-dim vector packs to 1536 bytes., Empty matrix → empty array., Single row matches cosine_similarity., Multiple rows ranked correctly., Zero query → all zeros., TestBatchCosineSimilarity (+8 more) ### Community 73 - "Community 73" -Cohesion: 0.19 -Nodes (3): parseDateRange(), TestParseDateRange, TestParseDateRange +Cohesion: 0.16 +Nodes (7): _parse_date(), parseDate(), parseDateEnd(), parseDateRange(), parseDateStart(), TestParseDateRange, TestParseDateRange ### Community 74 - "Community 74" Cohesion: 0.11 @@ -976,16 +980,16 @@ Cohesion: 0.05 Nodes (44): cn(), AlertDialogAction(), AlertDialogCancel(), AlertDialogContent(), AlertDialogDescription(), AlertDialogFooter(), AlertDialogHeader(), AlertDialogMedia() (+36 more) ### Community 80 - "Community 80" -Cohesion: 0.14 -Nodes (19): buildSummary(), charCount(), countTokens(), dedup(), extractDecisions(), extractMetrics(), extractSnapshots(), extractTickers() (+11 more) +Cohesion: 0.15 +Nodes (16): buildSummary(), dedup(), extractDecisions(), extractMetrics(), extractSnapshots(), extractTickers(), extractToolCalls(), fetchFieldsPayload() (+8 more) ### Community 81 - "Community 81" -Cohesion: 0.15 -Nodes (13): getLiveCotation(), Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th (+5 more) +Cohesion: 0.09 +Nodes (17): getLiveCotation(), JSONBytesResponse, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Sends pre-serialized JSON bytes without re-encoding (cache-friendly)., Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th (+9 more) ### Community 82 - "Community 82" -Cohesion: 0.11 -Nodes (16): arrowTypeFor(), buildCotationDateIndex(), buildFeatherCache(), buildTickerIndex(), optimizeDtypes(), P1: establish the sorted-cache invariant once at load/refresh. Sorts by (, P1: first-occurrence index over a sortCacheFrame-sorted frame. The cache, Get cached stocks data with optional column filtering. (+8 more) +Cohesion: 0.09 +Nodes (27): buildFeatherCache(), Feather build / read helpers for the stocks cache. Owns the on-disk layout (CAC, Return (engine, featherPath, nestedPath), preferring live values on the cach, Return (engine, featherPath, nestedPath), preferring live values on the cach, readFeatherDataFrame(), _runtimeConf(), tryBuildLock(), arrowTypeFor() (+19 more) ### Community 83 - "Community 83" Cohesion: 0.1 @@ -1028,8 +1032,8 @@ Cohesion: 0.09 Nodes (21): aliases, components, hooks, lib, ui, utils, iconLibrary, menuAccent (+13 more) ### Community 93 - "Community 93" -Cohesion: 0.11 -Nodes (11): Pytest Testing, System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state. (+3 more) +Cohesion: 0.12 +Nodes (10): System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., TestSendMessageStateIntegration (+2 more) ### Community 94 - "Community 94" Cohesion: 0.12 @@ -1052,8 +1056,8 @@ Cohesion: 0.28 Nodes (6): extractTokenPayload(), Tests for extractTokenPayload — the standalone token extraction dependency., Create a mock Starlette Request with given headers., Authorization: Bearer (empty) — no token after Bearer., Authorization: Basic xxx — not Bearer, so no token found., TestExtractTokenPayload ### Community 99 - "Community 99" -Cohesion: 0.1 -Nodes (17): Covers lines 62-63, 65-68: PUT /prometheus/sessions/{sessionId}., Covers lines 62-63, 65-68: PUT /prometheus/sessions/{sessionId}., Covers lines 65-68: title updated successfully., Covers lines 65-68: title updated successfully., Covers lines 62-63, 65-68: PUT /prometheus/sessions/{sessionId}., Covers lines 65-68: title updated successfully., Covers lines 62-63: not the session owner., Covers lines 62-63: not the session owner. (+9 more) +Cohesion: 0.04 +Nodes (47): _make_prometheus_client(), Covers lines 95-98: session deleted., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 95-98: DELETE /prometheus/sessions/{sessionId}., Covers lines 95-98: session deleted., Covers lines 96-97: session not found. (+39 more) ### Community 100 - "Community 100" Cohesion: 0.16 @@ -1061,23 +1065,23 @@ Nodes (6): _assert_gemini_safe(), Assert a tool function has only Gemini-compati ### Community 101 - "Community 101" Cohesion: 0.07 -Nodes (20): Tests for connection pool configuration, Stocks engine should have optimized pool settings, Tests for lazy JSON deserialization, Query manager should have deserialize method, Integration tests for all query optimizations, All optimizations should be implemented, Query filter should use ticker index, Tests for optimized search filtering (+12 more) +Nodes (18): Different query parameters should not share cache, Cache should expire after TTL, Tests for connection pool configuration, Stocks engine should have optimized pool settings, Tests for lazy JSON deserialization, Query manager should have deserialize method, Performance tests for query operations, Query should respond within 1 second (+10 more) ### Community 102 - "Community 102" -Cohesion: 0.11 -Nodes (11): BaseSettings, BaseMansaSettings, DiscordSettings, MysqlSettings, OrunmilaSettings, PrometheusSettings, ScraperSettings, StocksApiSettings (+3 more) +Cohesion: 0.15 +Nodes (8): BaseSettings, BaseMansaSettings, DiscordSettings, MysqlSettings, OrunmilaSettings, ScraperSettings, StocksApiSettings, UserSettings ### Community 103 - "Community 103" Cohesion: 0.13 Nodes (14): 10. Performance, 11. Testing, 12. Risks, 13. Out of Scope (YAGNI), 14. Open Questions, 1. Executive Summary, 2. Context & Motivation, 5. Architecture Decision (+6 more) ### Community 104 - "Community 104" -Cohesion: 0.14 -Nodes (13): benchOnce(), main(), batchCosineSimilarity(), decodeEmbeddings(), normalizeRows(), Empty matrix → empty array., Single row matches cosine_similarity., Multiple rows ranked correctly. (+5 more) +Cohesion: 0.2 +Nodes (14): benchOnce(), main(), _fulltext_search(), fullTextSearch(), minMax(), scoreCandidates(), scoreRecency(), scoreRow() (+6 more) ### Community 105 - "Community 105" -Cohesion: 0.12 -Nodes (10): Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Tests covering query.py lines 50-67., Tests covering query.py lines 50-67., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Tests covering query.py lines 50-67., Tests covering query.py lines 50-67. (+2 more) +Cohesion: 0.21 +Nodes (7): ResultCache — SHA256-keyed file-based cache for computed results., File-based cache keyed by SHA256 of code. Stores results as JSON under:, Return cached result dict or None if miss., Store result with timestamp., Delete all cached results for a session., Check if a result exists for the given code., ResultCache ### Community 106 - "Community 106" Cohesion: 0.22 @@ -1120,8 +1124,8 @@ Cohesion: 0.17 Nodes (11): dateOnly(), EditDividendDialog(), EditLotDialog(), fmtBRL(), fmtMoney(), KIND_STYLES, lotTitle(), deleteDividend() (+3 more) ### Community 116 - "Community 116" -Cohesion: 0.11 -Nodes (21): create_memory(), createMemory(), embed(), _build_system_prompt(), buildSystemPrompt(), chatSession(), _execute_memory_tool(), executeMemoryTool() (+13 more) +Cohesion: 0.13 +Nodes (16): _build_system_prompt(), buildSystemPrompt(), chatSession(), _execute_memory_tool(), _get_client(), _get_memory_tools(), getClient(), openMCPClients() (+8 more) ### Community 117 - "Community 117" Cohesion: 0.15 @@ -1136,16 +1140,16 @@ Cohesion: 0.07 Nodes (26): code:python ("""Tests for SandboxManager file mutation helpers (delete_fi), code:python (from main.app.prometheus.sandbox import SandboxManager, host), code:python (@router.post("/workspace/upload")), code:bash (git add main/controller/prometheus_controller.py tests/test_), code:python (from unittest.mock import patch, MagicMock), code:python (from main.app.prometheus.sandbox import SandboxManager, host), code:python (async def serve_file(path: str, **_) -> dict:), code:python ("serve_file": serve_file,) (+18 more) ### Community 120 - "Community 120" -Cohesion: 0.08 -Nodes (40): _make_auth_client(), _make_prometheus_client(), Tests to cover uncovered lines across controllers, UserManager, and auth util., Covers lines 44-54, 63, 66-71: register success, ValueError, generic Exception., Covers lines 44-54, 63, 66-71: register success, ValueError, generic Exception., Covers lines 87-93, 102: login success and failure paths., Covers lines 87-93, 102: login success and failure paths., Return (client, app) with auth + user routers and mocked getSession. (+32 more) +Cohesion: 0.07 +Nodes (44): _make_auth_client(), Tests to cover uncovered lines across controllers, UserManager, and auth util., Return (client, app) with auth + user routers and mocked getSession., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136., Covers lines 126, 131, 135-136., Covers lines 126-136: DELETE /user/sessions/{sessionId}. (+36 more) ### Community 121 - "Community 121" Cohesion: 0.21 Nodes (12): code:python (import inspect), code:python (from main.app.prometheus.sandbox import SandboxManager), code:python (TOOL_REGISTRY: dict[str, Any] = {), code:python (## Code Sandbox (On-Demand)), code:bash (git add main/app/prometheus/agent.py), code:dockerfile (FROM python:3.11-slim), code:bash (git add Dockerfile.sandbox), Phase 6: Agent Integration (All Layers) (+4 more) ### Community 122 - "Community 122" -Cohesion: 0.14 -Nodes (11): test_setup_discord_handler_disabled(), test_setup_discord_handler_enabled(), TestSetupLogging, Many concurrent emit() calls must not create more threads than max_workers., Verify that DiscordHandler submits to a bounded executor, not raw threads., The module-level discordExecutor must exist with max_workers <= 5., DiscordHandler.emit() must use discordExecutor.submit, not Thread.start., TestDiscordHandlerThreadPool (+3 more) +Cohesion: 0.15 +Nodes (10): test_setup_discord_handler_disabled(), test_setup_discord_handler_enabled(), Many concurrent emit() calls must not create more threads than max_workers., Verify that DiscordHandler submits to a bounded executor, not raw threads., The module-level discordExecutor must exist with max_workers <= 5., DiscordHandler.emit() must use discordExecutor.submit, not Thread.start., TestDiscordHandlerThreadPool, DiscordHandler (+2 more) ### Community 123 - "Community 123" Cohesion: 0.17 @@ -1176,12 +1180,12 @@ Cohesion: 0.08 Nodes (25): 1.1 Functional (per surface; tags: EXISTS = build on it, PARTIAL = half reusable, MISSING = greenfield), 1.2 Non-functional, 1. Requirements, 2. Domain model, 3. API contracts (all under `/api/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout), 3. API contracts (all under `/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout), 4. Phased build plan (writing-plans: each phase independently reviewable; reviewer PASS per phase), 5. Risks / assumptions (honest flags carried over — do not treat as fact) (+17 more) ### Community 131 - "Community 131" -Cohesion: 0.23 -Nodes (9): Same input → same hash., Different inputs → different hashes., Returns 32-char hex string., TestContentHash, ALL(), content_hash(), contentHash(), MD5 hash for change detection. (+1 more) +Cohesion: 0.14 +Nodes (13): Same input → same hash., Different inputs → different hashes., Returns 32-char hex string., TestContentHash, ALL(), _extractCredential(), _introspectUrl(), introspectUser() (+5 more) ### Community 132 - "Community 132" Cohesion: 0.25 -Nodes (7): code:python (from dataclasses import dataclass), code:bash (git add main/app/wallet/__init__.py main/app/wallet/math.py ), code:python (from datetime import date), File Structure, Global Constraints, Task 3: Pure derivation math, Wallet Management (Thoth/Iyagba) Implementation Plan +Nodes (7): code:python ("""add wallet_holdings and wallet_lots tables), code:python (import main.models.wallet), code:bash (git add migrations/versions/wallet_tables_20260904_add_walle), File Structure, Global Constraints, Task 2: Alembic migration for wallet tables, Wallet Management (Thoth/Iyagba) Implementation Plan ### Community 133 - "Community 133" Cohesion: 0.18 @@ -1196,8 +1200,8 @@ Cohesion: 0.11 Nodes (4): cache(), Tests for ResultCache., TestColumnValidator, TestResultCache ### Community 136 - "Community 136" -Cohesion: 0.1 -Nodes (17): Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136., Covers lines 126, 131, 135-136., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136., Covers lines 127-129: session not found., Covers lines 127-129: session not found. (+9 more) +Cohesion: 0.12 +Nodes (10): Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Tests covering query.py lines 50-67., Tests covering query.py lines 50-67., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Tests covering query.py lines 50-67., Tests covering query.py lines 50-67. (+2 more) ### Community 137 - "Community 137" Cohesion: 0.18 @@ -1212,8 +1216,8 @@ Cohesion: 0.24 Nodes (6): Dataset, produce_data(), Train script for a single file Need to set the TPU address first: export XRT_TP, A class that handles the reddit data files, A class that handles one dataset, RedditDataset ### Community 140 - "Community 140" -Cohesion: 0.06 -Nodes (48): Base, BaseModel, OrunmilaMemory, PrometheusMemory, PrometheusMemory, MemoryCandidate, OrunmilaMemory, MemoryCandidate (+40 more) +Cohesion: 0.04 +Nodes (51): Base, PrometheusMemory, PrometheusMemory, OrunmilaSandbox, MemoryManager, PrometheusMemory, All memory operations. Stateless class methods., PrometheusService (+43 more) ### Community 141 - "Community 141" Cohesion: 0.24 @@ -1244,8 +1248,8 @@ Cohesion: 0.23 Nodes (3): categorizeColumns(), TestCategorizeColumns, TestCategorizeColumns ### Community 148 - "Community 148" -Cohesion: 0.07 -Nodes (24): Covers lines 114-115, 117-120, 122, 125: POST /prometheus/chat., Covers lines 114-115, 117-120, 122, 125: POST /prometheus/chat., Covers lines 111-112: sessionId is None, new session created., Covers lines 111-112: sessionId is None, new session created., Covers lines 109-136: POST /prometheus/chat/stream (SSE)., Covers lines 118-119: sessionId is None, new session created., Covers lines 114-115, 117-120, 122: existing session with verified ownership., Covers lines 114-115, 117-120, 122: existing session with verified ownership. (+16 more) +Cohesion: 0.09 +Nodes (19): Covers lines 114-115, 117-120, 122, 125: POST /prometheus/chat., Covers lines 114-115, 117-120, 122, 125: POST /prometheus/chat., Covers lines 111-112: sessionId is None, new session created., Covers lines 111-112: sessionId is None, new session created., Covers lines 109-136: POST /prometheus/chat/stream (SSE)., Covers lines 118-119: sessionId is None, new session created., Covers lines 114-115, 117-120, 122: existing session with verified ownership., Covers lines 114-115, 117-120, 122: existing session with verified ownership. (+11 more) ### Community 149 - "Community 149" Cohesion: 0.18 @@ -1261,7 +1265,7 @@ Nodes (12): _getDb(), Search user's saved memories, preferences, and past analys ### Community 153 - "Community 153" Cohesion: 0.11 -Nodes (17): Architecture, Auth/Users — Dual-Layer Session Security, CI Pipeline Order, code:bash (# Run (Docker)), Dev Commands, graphify, Key Quirks, Memory Keys (+9 more) +Nodes (18): Architecture, Auth/Users — Dual-Layer Session Security, CI Pipeline Order, Code Style, code:bash (# Run (Docker)), Dev Commands, graphify, Key Quirks (+10 more) ### Community 154 - "Community 154" Cohesion: 0.22 @@ -1276,8 +1280,8 @@ Cohesion: 0.22 Nodes (8): API Endpoints, code:env (#), code:bash (python __init__.py), code:mermaid (graph TD), License, Prometheus, Usage, Workflow ### Community 157 - "Community 157" -Cohesion: 0.17 -Nodes (12): getFundamental(), Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret (+4 more) +Cohesion: 0.15 +Nodes (13): getFundamental(), Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret (+5 more) ### Community 158 - "Community 158" Cohesion: 0.22 @@ -1324,8 +1328,8 @@ Cohesion: 0.4 Nodes (4): compilerOptions, baseUrl, paths, @/* ### Community 169 - "Community 169" -Cohesion: 0.17 -Nodes (12): getCotations(), Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur, Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur, Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur, Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur, Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur, Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur, Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur (+4 more) +Cohesion: 0.15 +Nodes (13): getCotations(), Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur, Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur, Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur, Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur, Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur, Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur, Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur (+5 more) ### Community 170 - "Community 170" Cohesion: 0.25 @@ -1376,8 +1380,8 @@ Cohesion: 0.14 Nodes (14): 3.0 Verified ground truth, 3.10 Migration sequence + verification, 3.1 Target topology, 3.2 Worker-container extraction, 3.3 nginx upstream evolution — validated against the user's plan, 3.4 TODO 13 migration — drop `{service}_HOST`/`{service}_PORT`, 3.5 Redis — exactly two jobs, 3.6 Cache strategy across boxes (+6 more) ### Community 184 - "Community 184" -Cohesion: 0.23 -Nodes (8): pack → unpack preserves values., Empty list roundtrips., 384-dim vector packs to 1536 bytes., TestPackUnpack, pack_vector(), Unpack MySQL BLOB to float list., Vectorized cosine similarity: one query against N embeddings., unpack_vector() +Cohesion: 0.33 +Nodes (4): Integration tests for all query optimizations, All optimizations should be implemented, Query filter should use ticker index, TestQueryOptimization ### Community 185 - "Community 185" Cohesion: 0.38 @@ -1412,8 +1416,8 @@ Cohesion: 0.33 Nodes (6): normalizer, clean_text, handle_chinese_chars, lowercase, strip_accents, type ### Community 194 - "Community 194" -Cohesion: 0.38 -Nodes (9): compactCotations(), compactRow(), compactValue(), compressResponse(), fixHeaders(), getAbbr(), getNest(), toColumnar() (+1 more) +Cohesion: 0.21 +Nodes (15): compactCotations(), compactRow(), compactValue(), compressResponse(), fixHeaders(), getAbbr(), getNest(), Abbreviation map for a frame (dependency-injected; no cache import). Result (+7 more) ### Community 195 - "Community 195" Cohesion: 0.33 @@ -1520,8 +1524,8 @@ Cohesion: 0.2 Nodes (9): Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148. (+1 more) ### Community 222 - "Community 222" -Cohesion: 0.1 -Nodes (15): generateKey(), JSONBytesResponse, listFields(), Sends pre-serialized JSON bytes without re-encoding (cache-friendly)., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental. (+7 more) +Cohesion: 0.18 +Nodes (11): listFields(), Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental. (+3 more) ### Community 223 - "Community 223" Cohesion: 0.4 @@ -1555,10 +1559,6 @@ Nodes (5): code:python (import pytest), code:python (import hashlib), code:bash Cohesion: 0.18 Nodes (11): 2.2.1 Complexity hotspots table (H1–H17 condensed to P0/P1/P2), 2.2.2 Blob inventory (LOC table + SRP evidence), 2.2.3 Mass data loads, 2.2.4 Phased fix roadmap (P0/P1/P2), §2.2 CODE EFFICIENCY — O(n²), Complexity & Blob Anti-Patterns, code:block4 (scraper.py:44 671 LOC — mass loads: SELECT * fetchma), code:powershell (ruff check . && ruff format --check .), code:powershell (pytest tests/test_stocks_cache_concurrency.py -v # ThreadPo) (+3 more) -### Community 231 - "Community 231" -Cohesion: 0.2 -Nodes (3): OrunmilaSession, createSession(), OrunmilaChatManager - ### Community 232 - "Community 232" Cohesion: 0.4 Nodes (5): Bucket A: Security Fixes (quick wins, 30 min), Bucket B: DB Session Cleanup (medium, 1-2 hrs), Bucket C: Testing (medium, 2-3 hrs), Bucket D: Infrastructure (large, 4+ hrs), Recommended Delegation Buckets @@ -1568,8 +1568,8 @@ Cohesion: 0.4 Nodes (5): 8. Build Sequence (4 phases, each independently shippable), Phase 0 — Sandbox foundation (1-2 days, no user-facing change), Phase 1 — MCP exposure of STOCKS_API (1 day), Phase 2 — Refactor PROMETHEUS to agentic (3-5 days, the big one), Phase 3 — Hardening (1-2 days, can ship incrementally) ### Community 234 - "Community 234" -Cohesion: 0.27 -Nodes (16): OrunmilaSandbox, create(), delete_file(), destroy(), execute(), getClient(), getOrCreate(), hostPath() (+8 more) +Cohesion: 0.32 +Nodes (14): create(), delete_file(), destroy(), execute(), getClient(), getOrCreate(), hostPath(), list_files() (+6 more) ### Community 236 - "Community 236" Cohesion: 0.5 @@ -1616,8 +1616,8 @@ Cohesion: 0.5 Nodes (4): Category 5: Error Handling Gaps (MEDIUM), Issue 5.1 — Generic exception handler swallows traceback in production, Issue 5.2 — DiscordHandler sends only message, not traceback, Issue 5.3 — `_build_error_response` ignores `status_code` parameter ### Community 251 - "Community 251" -Cohesion: 0.09 -Nodes (17): client(), pytest_configure(), TestClient with all routers mounted — no lifespan (no DB/service init). O, Set required env vars before test collection. config.py eagerly instantia, Reset slowapi in-memory rate limiter between every test., Set required env vars before test collection. config.py eagerly instantia, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O (+9 more) +Cohesion: 0.17 +Nodes (6): pytest_configure(), Set required env vars before test collection. config.py eagerly instantia, Reset slowapi in-memory rate limiter between every test., Set required env vars before test collection. config.py eagerly instantia, Set required env vars before test collection. config.py eagerly instantia, _reset_rate_limiter() ### Community 252 - "Community 252" Cohesion: 0.5 @@ -1660,8 +1660,8 @@ Cohesion: 0.22 Nodes (8): 1. Prime owns the goal, lanes own the work, 2. Dispatch: `delegate()`, one per lane, one turn, 3. Delegate toolsets vary — verify each lane, 4. Trust nothing — verify everything, 5. Windows PowerShell survival, 6. Finish per lane, not per swarm, 7. Standing bans (this repo), SWARMS.md — subagent swarm playbook (OpenCode / Hermes) ### Community 474 - "Community 474" -Cohesion: 0.15 -Nodes (11): _count_memories(), _create_memory(), _get_memory(), Keys with Jaccard > 0.8 should merge., Keys with Jaccard > 0.8 should merge., Keys with low similarity should not merge., Keys with low similarity should not merge., Keys with low similarity should not merge. (+3 more) +Cohesion: 0.17 +Nodes (4): POST /memories rejects missing key., POST /memories rejects missing value., Full integration tests using mocked MemoryManager., TestMemoryEndpointsIntegration ### Community 475 - "Community 475" Cohesion: 0.15 @@ -1691,10 +1691,6 @@ Nodes (4): code:python (def test_extract_temporal_info():), code:python (# main/ Cohesion: 0.5 Nodes (4): code:python (def test_session_scoped_memory(db_session, sample_user):), code:python (# Add to main/models/memory.py), code:bash (git add main/models/memory.py main/app/prometheus/memory.py ), Task 8: Session Scoping -### Community 482 - "Community 482" -Cohesion: 0.11 -Nodes (4): FastAPI, Tests for inline pagination params (used in user + prometheus controllers)., TestPaginationParams, PaginationParams - ### Community 483 - "Community 483" Cohesion: 0.5 Nodes (4): code:python (def test_consolidation_preserves_decisions():), code:python (# Add to main/app/prometheus/summarizer.py), code:bash (git add main/app/prometheus/summarizer.py tests/test_consoli), Task 9: Memory Consolidation @@ -1724,28 +1720,28 @@ Cohesion: 0.22 Nodes (8): API Endpoints, code:env (ORUNMILA_ENABLED=TRUE), code:bash (python run.py), code:mermaid (graph TD), License, Orunmila, Usage, Workflow ### Community 491 - "Community 491" -Cohesion: 0.07 -Nodes (13): IntFlag, Covers line 28: GET /auth/health., Covers line 28: GET /auth/health., Covers lines 139, 141-149: googleLogin endpoint., Covers lines 139, 141-149: googleLogin endpoint., TestGoogleLogin, TestHealthEndpoint, Tests for main/utils/roles.py — covers requirePermission and edge cases. (+5 more) +Cohesion: 0.1 +Nodes (4): Tests for main/utils/roles.py — covers requirePermission and edge cases., TestCheckAccess, TestRequirePermission, TestRolesHierarchy ### Community 492 - "Community 492" Cohesion: 0.33 Nodes (5): Baseline (lane 4), Export recipe, Move triggers (any one fires the migration), Options, Vector Scale-Up Runbook ### Community 493 - "Community 493" -Cohesion: 0.18 -Nodes (10): Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB. (+2 more) +Cohesion: 0.05 +Nodes (37): Covers line 27: user already has the role., Covers line 27: user already has the role., Covers line 27: user already has the role., Covers line 27: user already has the role., Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC (+29 more) ### Community 495 - "Community 495" Cohesion: 0.05 Nodes (42): 0. The blockers, ranked, 1.1 Process model — exactly one process, several threads, 1.1 Runtime topology — one process, many threads, 1.2 Cache (post-refactor) — RAM sharing works, 1.2 The cache is already the right shape for multi-process, 1.3 Per-process resources that multiply with N workers, 1.3 Per-process state that multiplies with N, 1. Verified current state (+34 more) ### Community 497 - "Community 497" -Cohesion: 0.21 -Nodes (6): buildSystemPrompt(), getClient(), Orunmila, persistEvent(), OrunmilaCompactor, newTokenCache() +Cohesion: 0.19 +Nodes (5): buildSystemPrompt(), getClient(), persistEvent(), OrunmilaCompactor, newTokenCache() ### Community 498 - "Community 498" -Cohesion: 0.17 -Nodes (7): Different query parameters should not share cache, Cache should expire after TTL, Tests for query result caching, CacheManager should track cached queries, Query cache should have configurable TTL, getCachedStocks should support column filtering, TestQueryCaching +Cohesion: 0.33 +Nodes (5): Tests for optimized search filtering, Filter should use ticker index for O(1) lookup, Tests for optimized search filtering, Filter should use ticker index for O(1) lookup, TestFilterBySearchTerms ### Community 499 - "Community 499" Cohesion: 0.2 @@ -1760,16 +1756,16 @@ Cohesion: 0.22 Nodes (3): getCurrentSession(), getSessions(), sessionToDict() ### Community 502 - "Community 502" -Cohesion: 0.07 -Nodes (22): Tests for connection pool configuration, Tests for connection pool configuration, Stocks engine should have optimized pool settings, Stocks engine should have optimized pool settings, Tests for lazy JSON deserialization, Tests for lazy JSON deserialization, Query manager should have deserialize method, Query manager should have deserialize method (+14 more) +Cohesion: 0.11 +Nodes (15): Tests for connection pool configuration, Tests for connection pool configuration, Stocks engine should have optimized pool settings, Stocks engine should have optimized pool settings, Tests for lazy JSON deserialization, Tests for lazy JSON deserialization, Query manager should have deserialize method, Query manager should have deserialize method (+7 more) ### Community 503 - "Community 503" Cohesion: 0.17 Nodes (7): Tests for dynamic ticker index feature, Ticker index should be built when cache is loaded, Ticker index should contain all tickers from cache, Ticker index should be case-insensitive, Looking up ticker should return valid row index, Ticker index should be rebuilt when cache refreshes, TestTickerIndex ### Community 504 - "Community 504" -Cohesion: 0.29 -Nodes (6): dbSession(), Tests for atomic API key quota enforcement (race condition fix). Verifies tha, Sample API key data for tests., Create an in-memory SQLite database for testing., Sample API key data for tests., sampleKeyData() +Cohesion: 0.18 +Nodes (6): System prompt should include state context when provided., System prompt should not include state section when empty., State section should appear after memories section., All state entries should appear in the prompt., System prompt should work without state parameter., TestBuildSystemPromptState ### Community 505 - "Community 505" Cohesion: 0.33 @@ -1791,10 +1787,6 @@ Nodes (5): Disputed (already litigated — needs your ruling to proceed), Held o Cohesion: 0.6 Nodes (3): bench(), main(), stats() -### Community 511 - "Community 511" -Cohesion: 0.29 -Nodes (6): Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., TestStocksApiHealth - ### Community 512 - "Community 512" Cohesion: 0.18 Nodes (11): 2.0 Grounding: what the code actually does, 2.1 Hypotheses, 2.3 Scenarios, 2.4 Protocol, 2.5 Metrics, 2.6 Acceptance thresholds — **ALL PROPOSED, freeze after first real run**, 2.7 Results doc layout, 2.8 Feeding `/status` (TODO 14) (+3 more) @@ -1804,12 +1796,12 @@ Cohesion: 0.2 Nodes (16): baseFrame(), deserializeJsonColumns(), envelope(), fetchLivePayload(), filterBySearchTerms(), _filterCotationByDate(), filterCotationData(), finalize() (+8 more) ### Community 518 - "Community 518" -Cohesion: 0.06 -Nodes (29): memoryMaintenance(), create_memories(), Zero access but score still above threshold → not archived., Even with low score, if accessed → not archived., Even with low score, if accessed → not archived., Already archived memories are skipped., Already archived memories are skipped., Decay happens first, then archive check with new scores. (+21 more) +Cohesion: 0.11 +Nodes (12): create_memories(), Zero access but score still above threshold → not archived., Already archived memories are skipped., Already archived memories are skipped., Helper to create memories with controlled baseScore, lastAccessedAt, accessCount, Helper to create memories with controlled baseScore, lastAccessedAt, accessCount, Decay applies to ALL active memories, not just accessed ones., Decay applies to ALL active memories, not just accessed ones. (+4 more) ### Community 519 - "Community 519" -Cohesion: 0.57 -Nodes (6): addRole(), addRoleToUser(), getCurrentUser(), getRolesList(), hasRole(), toDict() +Cohesion: 0.26 +Nodes (10): introspectToken(), verifyAccessToken(), introspect(), FastAPI, addRole(), addRoleToUser(), getCurrentUser(), getRolesList() (+2 more) ### Community 520 - "Community 520" Cohesion: 0.16 @@ -1824,12 +1816,12 @@ Cohesion: 0.18 Nodes (11): 2.0 Grounding: what the code actually does, 2.1 Hypotheses, 2.3 Scenarios, 2.4 Protocol, 2.5 Metrics, 2.6 Acceptance thresholds — **ALL PROPOSED, freeze after first real run**, 2.7 Results doc layout, 2.8 Feeding `/status` (TODO 14) (+3 more) ### Community 523 - "Community 523" -Cohesion: 0.43 -Nodes (4): _extractCredential(), _introspectUrl(), introspectUser(), _serviceToken() +Cohesion: 0.24 +Nodes (5): lifespan(), status(), checkDatabaseConnection(), checkSingleDb(), runMigrations() ### Community 524 - "Community 524" -Cohesion: 0.1 -Nodes (20): introspectToken(), verifyAccessToken(), introspect(), Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers line 16: empty password raises ValueError., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 45-51: verifyAccessToken with expired and invalid tokens. (+12 more) +Cohesion: 0.11 +Nodes (17): Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers line 16: empty password raises ValueError., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 48-49: jwt.ExpiredSignatureError. (+9 more) ### Community 525 - "Community 525" Cohesion: 0.11 @@ -1844,8 +1836,8 @@ Cohesion: 0.18 Nodes (11): Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback. (+3 more) ### Community 529 - "Community 529" -Cohesion: 0.29 -Nodes (6): GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422. +Cohesion: 0.33 +Nodes (6): dispatchToolCall must route memory tool names via TOOL_REGISTRY., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., TestDispatchRoutesMemoryTools ### Community 532 - "Community 532" Cohesion: 0.5 @@ -1860,12 +1852,12 @@ Cohesion: 0.5 Nodes (4): LATER (P2 — when touching these files), NOW (P0 — fix before next release), Priority Matrix, SOON (P1 — fix within 2 weeks) ### Community 535 - "Community 535" -Cohesion: 0.21 -Nodes (7): ResultCache — SHA256-keyed file-based cache for computed results., File-based cache keyed by SHA256 of code. Stores results as JSON under:, Return cached result dict or None if miss., Store result with timestamp., Delete all cached results for a session., Check if a result exists for the given code., ResultCache +Cohesion: 0.18 +Nodes (11): client(), TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with stocks router + verifyAPIKey + getCurrentUser overrides., TestClient with all routers mounted — no lifespan (no DB/service init). O (+3 more) ### Community 536 - "Community 536" -Cohesion: 0.25 -Nodes (6): initialize(), initialize(), P5: register memory maintenance on the shared scheduler. Kept in this ser, registerMemoryMaintenanceJob(), getApp(), runAll() +Cohesion: 0.14 +Nodes (12): initialize(), P5: register memory maintenance on the shared scheduler. Kept in this ser, registerMemoryMaintenanceJob(), initialize(), P5: register the session-cleanup job on the shared scheduler. Kept in thi, registerSessionCleanupJobs(), UserService, getSharedScheduler() (+4 more) ### Community 538 - "Community 538" Cohesion: 0.14 @@ -1891,10 +1883,6 @@ Nodes (3): at, label, rows Cohesion: 0.2 Nodes (9): Invalid date format raises exception (line 132)., Invalid date format raises exception (line 132)., Invalid date format raises exception (line 132)., Invalid date format raises exception (line 132)., Invalid date format raises exception (line 132)., Invalid date format raises exception (line 132)., Invalid date format raises exception (line 132)., Invalid date format raises exception (line 132). (+1 more) -### Community 544 - "Community 544" -Cohesion: 0.29 -Nodes (6): Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 48-49: jwt.ExpiredSignatureError. - ### Community 545 - "Community 545" Cohesion: 0.29 Nodes (7): code:python (def test_split_cliff_no_fake_loss_on_adjusted_series(monkeyp), code:python (def test_snapshot_includes_received_and_cash_gain(dbSession,), code:python (def test_history_merges_dividend_receipts(dbSession, sampleU), code:python (def test_ex_div_methodology_decides_received_stacking(dbSess), code:python (def ex_div_smoothing_verdict(padrao_before: float, padrao_af), code:bash (git add main/app/wallet/manager.py main/controller/wallet_co), Task 12: Split-cliff regression test + snapshot/history dividend extension + final gate @@ -1956,12 +1944,8 @@ Cohesion: 0.5 Nodes (4): code:python (import pytest), code:python (import logging), code:bash (git add main/app/wallet/prices.py tests/test_wallet_prices.p), Task 6: Price client — one batched STOCKS_API fetch per snapshot ### Community 560 - "Community 560" -Cohesion: 0.29 -Nodes (6): Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation. - -### Community 562 - "Community 562" -Cohesion: 0.29 -Nodes (6): GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422. +Cohesion: 0.22 +Nodes (4): Authentication System, Google OAuth, JWT Authentication, TestSessionExpiryConfig ### Community 563 - "Community 563" Cohesion: 0.33 @@ -1988,8 +1972,8 @@ Cohesion: 0.11 Nodes (16): Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 17, 22-27: user found, role not present, role added. (+8 more) ### Community 569 - "Community 569" -Cohesion: 0.33 -Nodes (3): initialize(), MCPDetectMiddleware, StocksAPIService +Cohesion: 0.14 +Nodes (8): initialize(), initialize(), OrunmilaService, initialize(), MCPDetectMiddleware, StocksAPIService, getApp(), runAll() ### Community 570 - "Community 570" Cohesion: 0.33 @@ -2000,8 +1984,8 @@ Cohesion: 0.29 Nodes (7): check_cache(), Read a file from the sandbox filesystem. Args: path: Absolute pa, List files in the workspace directory. Args: path: Directory pat, Upload a file to the sandbox filesystem. Use this to push data files (CSV,, Check if a computed result exists in the cache. Use before executing expens, read_sandbox_file(), upload_to_sandbox() ### Community 572 - "Community 572" -Cohesion: 0.27 -Nodes (4): Test that invalid API key returns zero rows affected., Test that multiple API keys have independent quotas., Test that invalid API key returns zero rows affected., Test that multiple API keys have independent quotas. +Cohesion: 0.39 +Nodes (8): _build_error_response(), buildErrorResponse(), generic_exception_handler(), genericExceptionHandler(), http_exception_handler(), httpExceptionHandler(), validation_exception_handler(), validationExceptionHandler() ### Community 573 - "Community 573" Cohesion: 0.25 @@ -2016,8 +2000,8 @@ Cohesion: 0.33 Nodes (5): replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34). ### Community 578 - "Community 578" -Cohesion: 0.33 -Nodes (5): Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval. +Cohesion: 0.47 +Nodes (3): TestCleanup, cleanup(), Close the main thread's session at interpreter shutdown. ### Community 579 - "Community 579" Cohesion: 0.33 @@ -2036,28 +2020,28 @@ Cohesion: 0.13 Nodes (14): 1.1 Functional (per surface; tags: EXISTS = build on it, PARTIAL = half reusable, MISSING = greenfield), 1.2 Non-functional, 1. Requirements, 2. Domain model, 3. API contracts (all under `/api/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout), 4. Phased build plan (writing-plans: each phase independently reviewable; reviewer PASS per phase), 5. Risks / assumptions (honest flags carried over — do not treat as fact), 6.1 DB & migrations (`user_db`) — READY, 2 actions (+6 more) ### Community 584 - "Community 584" -Cohesion: 0.13 -Nodes (13): Covers lines 95-98: session deleted., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 95-98: DELETE /prometheus/sessions/{sessionId}., Covers lines 95-98: session deleted., Covers lines 96-97: session not found., Covers lines 95-98: DELETE /prometheus/sessions/{sessionId}. (+5 more) +Cohesion: 0.32 +Nodes (4): memoryMaintenance(), _create(), After 10 cycles, preference (0.99^10) > context (0.90^10)., TestTypeAwareDecay ### Community 585 - "Community 585" Cohesion: 0.33 Nodes (5): Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Regression: HarnessState must never leak into tool signatures., Regression: HarnessState must never leak into tool signatures., TestGeminiCompatibility ### Community 586 - "Community 586" -Cohesion: 0.21 -Nodes (6): B3Scraper, initialize(), P5: register the scraper cron jobs on the shared scheduler. Kept in this, registerScraperJobs(), runScraper(), ScraperService +Cohesion: 0.24 +Nodes (4): Pytest Testing, PrometheusSettings, TestSandboxConfig, TestConfig ### Community 587 - "Community 587" Cohesion: 0.4 Nodes (5): Category 8: Testing Gaps (MEDIUM), Issue 8.1 — No integration tests for full request lifecycle, Issue 8.2 — No tests for scraper, stocks query, or cache, Issue 8.3 — No tests for Google OAuth callback, Issue 8.4 — No tests for session cleanup ### Community 588 - "Community 588" -Cohesion: 0.33 -Nodes (5): Covers line 27: user already has the role., Covers line 27: user already has the role., Covers line 27: user already has the role., Covers line 27: user already has the role., Covers lines 42-44: session validation fails. +Cohesion: 0.29 +Nodes (6): GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422. ### Community 589 - "Community 589" -Cohesion: 0.15 -Nodes (12): dispatchToolCall must route memory tool names via TOOL_REGISTRY., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., dispatchToolCall must route memory tool names to executeMemoryTool., makeChat must include MEMORY_TOOLS alongside MCP sessions., dispatchToolCall must route memory tool names to executeMemoryTool. (+4 more) +Cohesion: 0.33 +Nodes (6): makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., TestMakeChatIncludesMemoryTools ### Community 590 - "Community 590" Cohesion: 0.29 @@ -2068,8 +2052,8 @@ Cohesion: 0.4 Nodes (4): 0. Purpose and constraints, Next actions (not in scope here), nginx Scaling Plan — reverse proxy + response cache for `/stocks`, and the multi-server evolution, Open decisions (blocking or product-owned) ### Community 592 - "Community 592" -Cohesion: 0.33 -Nodes (5): Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails. +Cohesion: 0.17 +Nodes (7): Decay happens first, then archive check with new scores., Decay happens first, then archive check with new scores., Score that decays to >= threshold stays alive. 0.11 * 0.95 = 0.1045 >= 0.1., Score that decays to >= threshold stays alive. 0.12 * 0.90 = 0.108 >= 0.1., 89 days with low score → not archived (need > 90)., 89 days with low score → not archived (need > 90)., TestDecayAndArchiveTogether ### Community 593 - "Community 593" Cohesion: 0.5 @@ -2083,10 +2067,6 @@ Nodes (4): 1.4 Phase P1 — cache locations, TTL table, directives, code:nginx ( Cohesion: 0.19 Nodes (7): Tests for thread safety utilities (Issues 5 & 6). Issue 5: DiscordHandler use, Verify getSession returns thread-local sessions under concurrency., getSession() must give each thread its own Session., connectivity.checkServiceConnection must call getSession(), not use a global Ses, connectivity.checkServiceConnection must call getSession(), not use a global Ses, TestConcurrentGetSession, TestConcurrentHttpProxy -### Community 596 - "Community 596" -Cohesion: 0.2 -Nodes (9): ResponseCache, autoAbbreviate(), dedupAbbrev(), detectNestedFields(), generateAbbreviations(), _parse_date(), parseDate(), parseDateEnd() (+1 more) - ### Community 597 - "Community 597" Cohesion: 0.5 Nodes (4): 1.3 Phase P0 — nginx service + config skeleton, code:yaml (nginx:), code:nginx (proxy_cache_path /var/cache/nginx/stocks), code:nginx (upstream stocks_api {) @@ -2096,67 +2076,67 @@ Cohesion: 0.5 Nodes (4): 1.4 Phase P1 — cache locations, TTL table, directives, code:nginx (proxy_pass http://stocks_api;), code:nginx (server {), code:bash (K=sk_test_...; U='http://localhost/stocks/historical?search=) ### Community 599 - "Community 599" -Cohesion: 0.38 -Nodes (9): Tests for main/utils/logging_config.py — covers DiscordHandler branches., test_discord_disabled(), test_discord_no_webhook(), test_exception_in_submit(), test_level_below_error(), test_message_truncation(), test_submit_called_on_error(), test_with_exception_info() (+1 more) +Cohesion: 0.33 +Nodes (10): Tests for main/utils/logging_config.py — covers DiscordHandler branches., test_discord_disabled(), test_discord_no_webhook(), test_exception_in_submit(), test_level_below_error(), test_message_truncation(), test_submit_called_on_error(), test_with_exception_info() (+2 more) + +### Community 600 - "Community 600" +Cohesion: 0.22 +Nodes (7): Integration tests for all query optimizations, Integration tests for all query optimizations, All optimizations should be implemented, All optimizations should be implemented, Query filter should use ticker index, Query filter should use ticker index, TestQueryOptimization ### Community 602 - "Community 602" -Cohesion: 0.24 -Nodes (5): lifespan(), status(), checkDatabaseConnection(), checkSingleDb(), runMigrations() +Cohesion: 0.32 +Nodes (7): create_memory(), createMemory(), _downloadModel(), embed(), getEmbeddingModel(), executeMemoryTool(), executeMemoryTool() ### Community 603 - "Community 603" Cohesion: 0.4 Nodes (5): Tests covering key.py lines 15-40. Uses asyncio.run() since pytest-asyncio, Tests covering key.py lines 15-40. Uses asyncio.run() since pytest-asyncio, Tests covering key.py lines 15-40. Uses asyncio.run() since pytest-asyncio, Tests covering key.py lines 15-40. Uses asyncio.run() since pytest-asyncio, TestVerifyAPIKey +### Community 604 - "Community 604" +Cohesion: 0.29 +Nodes (6): dbSession(), Tests for atomic API key quota enforcement (race condition fix). Verifies tha, Sample API key data for tests., Create an in-memory SQLite database for testing., Sample API key data for tests., sampleKeyData() + ### Community 605 - "Community 605" -Cohesion: 0.4 -Nodes (4): _downloadModel(), getEmbeddingModel(), initialize(), OrunmilaService +Cohesion: 0.29 +Nodes (6): Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., TestStocksApiHealth ### Community 606 - "Community 606" -Cohesion: 0.22 -Nodes (4): Authentication System, Google OAuth, JWT Authentication, TestSessionExpiryConfig - -### Community 607 - "Community 607" -Cohesion: 0.39 -Nodes (8): _build_error_response(), buildErrorResponse(), generic_exception_handler(), genericExceptionHandler(), http_exception_handler(), httpExceptionHandler(), validation_exception_handler(), validationExceptionHandler() - -### Community 609 - "Community 609" -Cohesion: 0.2 -Nodes (8): Covers lines 57-60: admin bypasses permission check and generates key., Covers lines 57-60: admin bypasses permission check and generates key., Covers lines 57-60: admin bypasses permission check and generates key., Covers lines 57-60: admin bypasses permission check and generates key., Covers lines 61-63: exception during key generation (admin path)., Covers lines 61-63: exception during key generation (admin path)., Covers lines 61-63: exception during key generation (admin path)., Covers lines 61-63: exception during key generation (admin path). - -### Community 610 - "Community 610" -Cohesion: 0.33 -Nodes (5): Covers line 24: GET /prometheus/health., Covers line 24: GET /prometheus/health., Covers line 24: GET /prometheus/health., Covers line 24: GET /prometheus/health., TestPrometheusHealth +Cohesion: 0.29 +Nodes (6): GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422. -### Community 612 - "Community 612" -Cohesion: 0.47 -Nodes (3): TestCleanup, cleanup(), Close the main thread's session at interpreter shutdown. +### Community 608 - "Community 608" +Cohesion: 0.27 +Nodes (4): Test that invalid API key returns zero rows affected., Test that multiple API keys have independent quotas., Test that invalid API key returns zero rows affected., Test that multiple API keys have independent quotas. -### Community 615 - "Community 615" +### Community 618 - "Community 618" Cohesion: 0.5 -Nodes (4): code:python ("""add wallet_holdings and wallet_lots tables), code:python (import main.models.wallet), code:bash (git add migrations/versions/wallet_tables_20260904_add_walle), Task 2: Alembic migration for wallet tables +Nodes (4): code:python (from dataclasses import dataclass), code:bash (git add main/app/wallet/__init__.py main/app/wallet/math.py ), code:python (from datetime import date), Task 3: Pure derivation math -### Community 617 - "Community 617" +### Community 621 - "Community 621" +Cohesion: 0.83 +Nodes (4): getMatrix(), getMatrixAsync(), matrixKey(), matrixUserTag() + +### Community 623 - "Community 623" Cohesion: 0.67 Nodes (3): checkServiceConnection — success, not found, errors., checkServiceConnection — success, not found, errors., TestCheckServiceConnection -### Community 618 - "Community 618" +### Community 624 - "Community 624" Cohesion: 0.67 Nodes (3): checkMySqlConnection — success, errors, engine=None paths., checkMySqlConnection — success, errors, engine=None paths., TestCheckMySqlConnection ## Knowledge Gaps -- **3350 isolated node(s):** `$schema`, `style`, `rsc`, `tsx`, `config` (+3345 more) +- **3360 isolated node(s):** `$schema`, `style`, `rsc`, `tsx`, `config` (+3355 more) These have ≤1 connection - possible missing edges or undocumented components. -- **233 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. +- **243 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. ## Suggested Questions _Questions this graph is uniquely positioned to answer:_ -- **Why does `Pytest Testing` connect `Community 93` to `Authentication Core`, `Frontend Components`, `Community 129`, `Data Models & Types`, `Community 518`, `Community 135`, `Community 138`, `Community 140`, `Community 527`, `Community 16`, `Community 18`, `Community 147`, `Community 24`, `Community 25`, `Community 27`, `Community 29`, `Community 32`, `Community 33`, `Community 40`, `Community 44`, `Community 49`, `Community 51`, `Community 59`, `Community 188`, `Community 61`, `Community 67`, `Community 595`, `Community 599`, `Community 600`, `Community 120`, `Community 477`, `Community 606`, `Community 482`, `Community 611`, `Community 100`, `Community 101`, `Community 102`, `Community 104`, `Community 491`, `Community 500`, `Community 502`, `Community 504`, `Community 251`?** +- **Why does `Pytest Testing` connect `Community 586` to `Authentication Core`, `Frontend Components`, `Community 129`, `Data Models & Types`, `Community 131`, `Community 518`, `Community 519`, `Community 135`, `Community 138`, `Community 140`, `Community 527`, `Community 16`, `Community 18`, `Community 147`, `Community 24`, `Community 25`, `Community 27`, `Community 29`, `Community 32`, `Community 33`, `Community 40`, `Community 44`, `Community 560`, `Community 49`, `Community 51`, `Community 186`, `Community 59`, `Community 188`, `Community 61`, `Community 584`, `Community 595`, `Community 599`, `Community 474`, `Community 604`, `Community 93`, `Community 477`, `Community 611`, `Community 100`, `Community 101`, `Community 491`, `Community 500`, `Community 502`, `Community 120`, `Community 251`, `Community 511`?** _High betweenness centrality (0.078) - this node is a cross-community bridge._ -- **Why does `FastAPI` connect `Community 482` to `Community 129`, `Community 517`, `Community 519`, `Community 523`, `Community 18`, `Community 147`, `Community 536`, `Community 33`, `Community 34`, `Community 40`, `Community 58`, `Community 576`, `Community 68`, `Community 71`, `Community 596`, `Community 84`, `Community 600`, `Community 602`, `Community 120`, `Community 477`, `Community 222`, `Community 606`, `Community 607`, `Community 491`, `Community 500`, `Community 501`, `Community 504`?** - _High betweenness centrality (0.036) - this node is a cross-community bridge._ -- **Why does `UserManager` connect `Community 45` to `Community 256`, `Prometheus Agent`, `Community 519`, `Community 136`, `Prometheus Memory`, `Community 140`, `Community 524`, `User Roles & Permissions`, `Community 141`, `Community 148`, `Community 22`, `Community 28`, `Community 541`, `Community 37`, `Community 172`, `Community 47`, `Community 565`, `Community 568`, `Community 58`, `Community 61`, `Community 67`, `Community 584`, `Community 603`, `Community 221`, `Community 610`, `Community 99`, `Community 105`, `Community 491`, `Community 107`, `Community 493`, `Community 112`, `Community 114`, `Community 120`, `Community 511`?** - _High betweenness centrality (0.031) - this node is a cross-community bridge._ +- **Why does `FastAPI` connect `Community 519` to `Community 129`, `Community 131`, `Community 517`, `Community 523`, `Community 18`, `Community 147`, `Community 33`, `Community 34`, `Community 40`, `Community 560`, `Community 569`, `Community 186`, `Community 58`, `Community 572`, `Community 68`, `Community 71`, `Community 73`, `Community 81`, `Community 84`, `Community 604`, `Community 477`, `Community 482`, `Community 612`, `Community 491`, `Community 500`, `Community 501`, `Community 120`, `Community 511`?** + _High betweenness centrality (0.050) - this node is a cross-community bridge._ +- **Why does `UserManager` connect `Community 45` to `Community 256`, `Prometheus Agent`, `Community 519`, `Community 136`, `Prometheus Memory`, `Community 524`, `Community 141`, `User Roles & Permissions`, `Community 148`, `Community 22`, `Community 28`, `Community 541`, `Community 37`, `Community 172`, `Community 47`, `Community 565`, `Community 568`, `Community 58`, `Community 61`, `Community 67`, `Community 474`, `Community 603`, `Community 605`, `Community 221`, `Community 99`, `Community 107`, `Community 493`, `Community 112`, `Community 114`, `Community 120`?** + _High betweenness centrality (0.027) - this node is a cross-community bridge._ - **Are the 72 inferred relationships involving `StocksCacheManager` (e.g. with `TestStocksCacheManager` and `TestVerifyAPIKey`) actually correct?** _`StocksCacheManager` has 72 INFERRED edges - model-reasoned connections that need verification._ - **Are the 52 inferred relationships involving `HarnessState` (e.g. with `Prometheus` and `.streamMessage()`) actually correct?** diff --git a/graphify-out/graph.json b/graphify-out/graph.json index 7e7c7f00..7eda6a52 100644 --- a/graphify-out/graph.json +++ b/graphify-out/graph.json @@ -237,7 +237,7 @@ "source_file": "config.py", "source_location": "L90", "id": "server_config_config", - "community": 140, + "community": 45, "norm_label": "config" }, { @@ -264,7 +264,7 @@ "source_file": "run.py", "source_location": "L1", "id": "run_py", - "community": 602, + "community": 523, "norm_label": "run.py" }, { @@ -273,7 +273,7 @@ "source_file": "run.py", "source_location": "L28", "id": "server_run_lifespan", - "community": 602, + "community": 523, "norm_label": "lifespan()" }, { @@ -282,7 +282,7 @@ "source_file": "run.py", "source_location": "L73", "id": "server_run_health", - "community": 602, + "community": 523, "norm_label": "health()" }, { @@ -291,7 +291,7 @@ "source_file": "run.py", "source_location": "L78", "id": "server_run_status", - "community": 602, + "community": 523, "norm_label": "status()" }, { @@ -300,7 +300,7 @@ "source_file": "run.py", "source_location": "L112", "id": "server_run_triggerscraper", - "community": 602, + "community": 523, "norm_label": "triggerscraper()" }, { @@ -2190,7 +2190,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L1", "id": "main_app_authentication_authentication_py", - "community": 576, + "community": 612, "norm_label": "authentication.py" }, { @@ -2208,7 +2208,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L16", "id": "authentication_authentication_createuseraccount", - "community": 576, + "community": 612, "norm_label": "createuseraccount()" }, { @@ -2217,7 +2217,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L51", "id": "authentication_authentication_authenticategoogleuser", - "community": 576, + "community": 612, "norm_label": "authenticategoogleuser()" }, { @@ -2235,7 +2235,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L79", "id": "authentication_authentication_resolveuniqueusername", - "community": 576, + "community": 612, "norm_label": "resolveuniqueusername()" }, { @@ -2253,7 +2253,7 @@ "source_file": "main/app/authentication/introspect.py", "source_location": "L1", "id": "main_app_authentication_introspect_py", - "community": 482, + "community": 519, "norm_label": "introspect.py" }, { @@ -2262,7 +2262,7 @@ "source_file": "main/app/authentication/introspect.py", "source_location": "L14", "id": "authentication_introspect_introspecttoken", - "community": 524, + "community": 519, "norm_label": "introspecttoken()" }, { @@ -2397,7 +2397,7 @@ "source_file": "main/app/authentication/util.py", "source_location": "L1", "id": "main_app_authentication_util_py", - "community": 606, + "community": 560, "norm_label": "util.py" }, { @@ -2433,7 +2433,7 @@ "source_file": "main/app/authentication/util.py", "source_location": "L44", "id": "authentication_util_verifyaccesstoken", - "community": 524, + "community": 519, "norm_label": "verifyaccesstoken()" }, { @@ -2487,7 +2487,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L208", "id": "orunmila_agent_orunmila", - "community": 497, + "community": 45, "norm_label": "orunmila" }, { @@ -2541,7 +2541,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L13", "id": "orunmila_chat_orunmilachatmanager", - "community": 231, + "community": 45, "norm_label": "orunmilachatmanager" }, { @@ -2937,7 +2937,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L64", "id": "orunmila_memory_memorycandidate", - "community": 140, + "community": 45, "norm_label": "memorycandidate" }, { @@ -2946,7 +2946,7 @@ "source_file": "", "source_location": "", "id": "basemodel", - "community": 140, + "community": 45, "norm_label": "basemodel" }, { @@ -3036,7 +3036,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L194", "id": "orunmila_memory_orunmilamemory", - "community": 140, + "community": 45, "norm_label": "orunmilamemory" }, { @@ -3171,7 +3171,7 @@ "source_file": "main/app/orunmila/sandbox.py", "source_location": "L51", "id": "orunmila_sandbox_sandboxmanager", - "community": 234, + "community": 45, "norm_label": "sandboxmanager" }, { @@ -3628,7 +3628,7 @@ "label": "getCurrentSelic()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L32", + "source_location": "L29", "id": "scraper_b3_scraper_getcurrentselic", "community": 21, "norm_label": "getcurrentselic()" @@ -3637,16 +3637,16 @@ "label": "B3Scraper", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L42", + "source_location": "L38", "id": "scraper_b3_scraper_b3scraper", - "community": 586, + "community": 21, "norm_label": "b3scraper" }, { "label": ".__init__()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L43", + "source_location": "L39", "id": "scraper_b3_scraper_b3scraper_init", "community": 21, "norm_label": ".__init__()" @@ -3655,7 +3655,7 @@ "label": "getInitialData()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L57", + "source_location": "L53", "id": "scraper_b3_scraper_getinitialdata", "community": 21, "norm_label": "getinitialdata()" @@ -3664,7 +3664,7 @@ "label": "historicalRentability()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L112", + "source_location": "L108", "id": "scraper_b3_scraper_historicalrentability", "community": 21, "norm_label": "historicalrentability()" @@ -3673,7 +3673,7 @@ "label": "historicalDividends()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L135", + "source_location": "L131", "id": "scraper_b3_scraper_historicaldividends", "community": 21, "norm_label": "historicaldividends()" @@ -3682,7 +3682,7 @@ "label": "historicalDividendYields()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L168", + "source_location": "L164", "id": "scraper_b3_scraper_historicaldividendyields", "community": 21, "norm_label": "historicaldividendyields()" @@ -3691,7 +3691,7 @@ "label": "historicalRevenue()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L196", + "source_location": "L192", "id": "scraper_b3_scraper_historicalrevenue", "community": 21, "norm_label": "historicalrevenue()" @@ -3700,7 +3700,7 @@ "label": "historicalCotationProfits()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L217", + "source_location": "L213", "id": "scraper_b3_scraper_historicalcotationprofits", "community": 21, "norm_label": "historicalcotationprofits()" @@ -3709,16 +3709,16 @@ "label": ".historicalCotationProfits_Oceans14()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L230", + "source_location": "L226", "id": "scraper_b3_scraper_b3scraper_historicalcotationprofits_oceans14", - "community": 586, + "community": 21, "norm_label": ".historicalcotationprofits_oceans14()" }, { "label": "historicalCotations()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L243", + "source_location": "L239", "id": "scraper_b3_scraper_historicalcotations", "community": 21, "norm_label": "historicalcotations()" @@ -3727,7 +3727,7 @@ "label": "tagAlong()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L260", + "source_location": "L256", "id": "scraper_b3_scraper_tagalong", "community": 21, "norm_label": "tagalong()" @@ -3736,7 +3736,7 @@ "label": "stockNews()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L281", + "source_location": "L277", "id": "scraper_b3_scraper_stocknews", "community": 21, "norm_label": "stocknews()" @@ -3745,63 +3745,63 @@ "label": ".fundamentalIndicators()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L294", + "source_location": "L290", "id": "scraper_b3_scraper_b3scraper_fundamentalindicators", - "community": 586, + "community": 21, "norm_label": ".fundamentalindicators()" }, { "label": ".processTicker()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L417", + "source_location": "L413", "id": "scraper_b3_scraper_b3scraper_processticker", - "community": 586, + "community": 21, "norm_label": ".processticker()" }, { "label": ".scrapeStocks()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L448", + "source_location": "L444", "id": "scraper_b3_scraper_b3scraper_scrapestocks", - "community": 586, + "community": 21, "norm_label": ".scrapestocks()" }, { "label": ".reorderColumns()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L495", + "source_location": "L491", "id": "scraper_b3_scraper_b3scraper_reordercolumns", - "community": 586, + "community": 21, "norm_label": ".reordercolumns()" }, { "label": ".serializeComplexTypes()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L504", + "source_location": "L500", "id": "scraper_b3_scraper_b3scraper_serializecomplextypes", - "community": 586, + "community": 21, "norm_label": ".serializecomplextypes()" }, { "label": ".exportJson()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L523", + "source_location": "L519", "id": "scraper_b3_scraper_b3scraper_exportjson", - "community": 586, + "community": 21, "norm_label": ".exportjson()" }, { "label": ".exportMysql()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L531", + "source_location": "L527", "id": "scraper_b3_scraper_b3scraper_exportmysql", - "community": 586, + "community": 21, "norm_label": ".exportmysql()" }, { @@ -3823,82 +3823,55 @@ "norm_label": "calculateinvestingscore()" }, { - "label": "cache.py", + "label": "build.py", "file_type": "code", - "source_file": "main/app/stocks_api/cache.py", + "source_file": "main/app/stocks_api/build.py", "source_location": "L1", - "id": "main_app_stocks_api_cache_py", - "community": 82, - "norm_label": "cache.py" - }, - { - "label": "optimizeDtypes()", - "file_type": "code", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L43", - "id": "stocks_api_cache_optimizedtypes", - "community": 82, - "norm_label": "optimizedtypes()" - }, - { - "label": "arrowTypeFor()", - "file_type": "code", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L63", - "id": "stocks_api_cache_arrowtypefor", + "id": "main_app_stocks_api_build_py", "community": 82, - "norm_label": "arrowtypefor()" + "norm_label": "build.py" }, { "label": "buildFeatherCache()", "file_type": "code", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L80", - "id": "stocks_api_cache_buildfeathercache", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L39", + "id": "stocks_api_build_buildfeathercache", "community": 82, "norm_label": "buildfeathercache()" }, { "label": "tryBuildLock()", "file_type": "code", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L171", - "id": "stocks_api_cache_trybuildlock", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L131", + "id": "stocks_api_build_trybuildlock", "community": 82, "norm_label": "trybuildlock()" }, { - "label": "sortCacheFrame()", - "file_type": "code", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L188", - "id": "stocks_api_cache_sortcacheframe", - "community": 82, - "norm_label": "sortcacheframe()" - }, - { - "label": "buildTickerIndex()", + "label": "readFeatherDataFrame()", "file_type": "code", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L198", - "id": "stocks_api_cache_buildtickerindex", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L148", + "id": "stocks_api_build_readfeatherdataframe", "community": 82, - "norm_label": "buildtickerindex()" + "norm_label": "readfeatherdataframe()" }, { - "label": "readFeatherDataFrame()", + "label": "cache.py", "file_type": "code", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L207", - "id": "stocks_api_cache_readfeatherdataframe", + "source_location": "L1", + "id": "main_app_stocks_api_cache_py", "community": 82, - "norm_label": "readfeatherdataframe()" + "norm_label": "cache.py" }, { "label": "StocksCacheManager", "file_type": "code", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L214", + "source_location": "L34", "id": "stocks_api_cache_stockscachemanager", "community": 42, "norm_label": "stockscachemanager" @@ -3907,7 +3880,7 @@ "label": ".__init__()", "file_type": "code", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L215", + "source_location": "L35", "id": "stocks_api_cache_stockscachemanager_init", "community": 42, "norm_label": ".__init__()" @@ -3916,7 +3889,7 @@ "label": ".snapshot()", "file_type": "code", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L223", + "source_location": "L43", "id": "stocks_api_cache_stockscachemanager_snapshot", "community": 42, "norm_label": ".snapshot()" @@ -3925,16 +3898,16 @@ "label": ".cacheScheduler()", "file_type": "code", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L227", + "source_location": "L47", "id": "stocks_api_cache_stockscachemanager_cachescheduler", - "community": 82, + "community": 536, "norm_label": ".cachescheduler()" }, { "label": ".loadFromFeather()", "file_type": "code", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L238", + "source_location": "L58", "id": "stocks_api_cache_stockscachemanager_loadfromfeather", "community": 82, "norm_label": ".loadfromfeather()" @@ -3943,7 +3916,7 @@ "label": ".getCachedStocks()", "file_type": "code", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L257", + "source_location": "L77", "id": "stocks_api_cache_stockscachemanager_getcachedstocks", "community": 82, "norm_label": ".getcachedstocks()" @@ -3961,7 +3934,7 @@ "label": "getAbbr()", "file_type": "code", "source_file": "main/app/stocks_api/compress.py", - "source_location": "L23", + "source_location": "L30", "id": "stocks_api_compress_getabbr", "community": 194, "norm_label": "getabbr()" @@ -3970,7 +3943,7 @@ "label": "getNest()", "file_type": "code", "source_file": "main/app/stocks_api/compress.py", - "source_location": "L31", + "source_location": "L43", "id": "stocks_api_compress_getnest", "community": 194, "norm_label": "getnest()" @@ -3979,7 +3952,7 @@ "label": "rebuildAbbrevs()", "file_type": "code", "source_file": "main/app/stocks_api/compress.py", - "source_location": "L41", + "source_location": "L59", "id": "stocks_api_compress_rebuildabbrevs", "community": 82, "norm_label": "rebuildabbrevs()" @@ -3988,7 +3961,7 @@ "label": "compactValue()", "file_type": "code", "source_file": "main/app/stocks_api/compress.py", - "source_location": "L46", + "source_location": "L65", "id": "stocks_api_compress_compactvalue", "community": 194, "norm_label": "compactvalue()" @@ -3997,7 +3970,7 @@ "label": "compactRow()", "file_type": "code", "source_file": "main/app/stocks_api/compress.py", - "source_location": "L67", + "source_location": "L86", "id": "stocks_api_compress_compactrow", "community": 194, "norm_label": "compactrow()" @@ -4006,7 +3979,7 @@ "label": "compactCotations()", "file_type": "code", "source_file": "main/app/stocks_api/compress.py", - "source_location": "L95", + "source_location": "L116", "id": "stocks_api_compress_compactcotations", "community": 194, "norm_label": "compactcotations()" @@ -4015,11 +3988,56 @@ "label": "compressResponse()", "file_type": "code", "source_file": "main/app/stocks_api/compress.py", - "source_location": "L130", + "source_location": "L151", "id": "stocks_api_compress_compressresponse", "community": 194, "norm_label": "compressresponse()" }, + { + "label": "frame.py", + "file_type": "code", + "source_file": "main/app/stocks_api/frame.py", + "source_location": "L1", + "id": "main_app_stocks_api_frame_py", + "community": 82, + "norm_label": "frame.py" + }, + { + "label": "optimizeDtypes()", + "file_type": "code", + "source_file": "main/app/stocks_api/frame.py", + "source_location": "L14", + "id": "stocks_api_frame_optimizedtypes", + "community": 82, + "norm_label": "optimizedtypes()" + }, + { + "label": "arrowTypeFor()", + "file_type": "code", + "source_file": "main/app/stocks_api/frame.py", + "source_location": "L34", + "id": "stocks_api_frame_arrowtypefor", + "community": 82, + "norm_label": "arrowtypefor()" + }, + { + "label": "sortCacheFrame()", + "file_type": "code", + "source_file": "main/app/stocks_api/frame.py", + "source_location": "L45", + "id": "stocks_api_frame_sortcacheframe", + "community": 82, + "norm_label": "sortcacheframe()" + }, + { + "label": "buildTickerIndex()", + "file_type": "code", + "source_file": "main/app/stocks_api/frame.py", + "source_location": "L55", + "id": "stocks_api_frame_buildtickerindex", + "community": 82, + "norm_label": "buildtickerindex()" + }, { "label": "key.py", "file_type": "code", @@ -4206,7 +4224,7 @@ "source_file": "main/app/stocks_api/sync_cache.py", "source_location": "L1", "id": "main_app_stocks_api_sync_cache_py", - "community": 82, + "community": 562, "norm_label": "sync_cache.py" }, { @@ -4215,34 +4233,25 @@ "source_file": "main/app/stocks_api/sync_cache.py", "source_location": "L14", "id": "stocks_api_sync_cache_cache", - "community": 82, + "community": 562, "norm_label": "cache()" }, { "label": "clearEndpointCache()", "file_type": "code", "source_file": "main/app/stocks_api/sync_cache.py", - "source_location": "L37", + "source_location": "L36", "id": "stocks_api_sync_cache_clearendpointcache", - "community": 82, + "community": 562, "norm_label": "clearendpointcache()" }, - { - "label": "Drop every cached endpoint body \u2014 called when the feather frame is replaced.", - "file_type": "rationale", - "source_file": "main/app/stocks_api/sync_cache.py", - "source_location": "L38", - "id": "stocks_api_sync_cache_rationale_38", - "community": 82, - "norm_label": "drop every cached endpoint body \u2014 called when the feather frame is replaced." - }, { "label": "util.py", "file_type": "code", "source_file": "main/app/stocks_api/util.py", "source_location": "L1", "id": "main_app_stocks_api_util_py", - "community": 596, + "community": 73, "norm_label": "util.py" }, { @@ -4251,7 +4260,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L17", "id": "stocks_api_util_dedupabbrev", - "community": 596, + "community": 194, "norm_label": "dedupabbrev()" }, { @@ -4260,23 +4269,23 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L26", "id": "stocks_api_util_autoabbreviate", - "community": 596, + "community": 194, "norm_label": "autoabbreviate()" }, { "label": "generateAbbreviations()", "file_type": "code", "source_file": "main/app/stocks_api/util.py", - "source_location": "L47", + "source_location": "L49", "id": "stocks_api_util_generateabbreviations", - "community": 596, + "community": 194, "norm_label": "generateabbreviations()" }, { "label": "categorizeColumns()", "file_type": "code", "source_file": "main/app/stocks_api/util.py", - "source_location": "L56", + "source_location": "L58", "id": "stocks_api_util_categorizecolumns", "community": 147, "norm_label": "categorizecolumns()" @@ -4285,16 +4294,16 @@ "label": "parseDate()", "file_type": "code", "source_file": "main/app/stocks_api/util.py", - "source_location": "L73", + "source_location": "L75", "id": "stocks_api_util_parsedate", - "community": 596, + "community": 73, "norm_label": "parsedate()" }, { "label": "parseDateRange()", "file_type": "code", "source_file": "main/app/stocks_api/util.py", - "source_location": "L85", + "source_location": "L87", "id": "stocks_api_util_parsedaterange", "community": 73, "norm_label": "parsedaterange()" @@ -4303,9 +4312,9 @@ "label": "detectNestedFields()", "file_type": "code", "source_file": "main/app/stocks_api/util.py", - "source_location": "L96", + "source_location": "L98", "id": "stocks_api_util_detectnestedfields", - "community": 596, + "community": 194, "norm_label": "detectnestedfields()" }, { @@ -4422,7 +4431,7 @@ "source_file": "main/controller/authentication_controller.py", "source_location": "L154", "id": "controller_authentication_controller_introspect", - "community": 524, + "community": 519, "norm_label": "introspect()" }, { @@ -4557,7 +4566,7 @@ "source_file": "main/controller/stocksapi_controller.py", "source_location": "L1", "id": "main_controller_stocksapi_controller_py", - "community": 222, + "community": 81, "norm_label": "stocksapi_controller.py" }, { @@ -4566,7 +4575,7 @@ "source_file": "main/controller/stocksapi_controller.py", "source_location": "L28", "id": "controller_stocksapi_controller_health", - "community": 222, + "community": 81, "norm_label": "health()" }, { @@ -4591,7 +4600,7 @@ "label": "getFundamental()", "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L157", + "source_location": "L163", "id": "controller_stocksapi_controller_getfundamental", "community": 157, "norm_label": "getfundamental()" @@ -4600,7 +4609,7 @@ "label": "getCotations()", "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L227", + "source_location": "L239", "id": "controller_stocksapi_controller_getcotations", "community": 169, "norm_label": "getcotations()" @@ -4609,7 +4618,7 @@ "label": "getLiveCotation()", "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L283", + "source_location": "L301", "id": "controller_stocksapi_controller_getlivecotation", "community": 81, "norm_label": "getlivecotation()" @@ -4636,8 +4645,8 @@ "label": "Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret", "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L167", - "id": "controller_stocksapi_controller_rationale_167", + "source_location": "L173", + "id": "controller_stocksapi_controller_rationale_173", "community": 157, "norm_label": "get point-in-time fundamental/valuation data for brazilian b3 stocks. ret" }, @@ -4645,8 +4654,8 @@ "label": "Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur", "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L235", - "id": "controller_stocksapi_controller_rationale_235", + "source_location": "L247", + "id": "controller_stocksapi_controller_rationale_247", "community": 169, "norm_label": "get 10-year daily price history (cotation) for brazilian b3 stocks. retur" }, @@ -4654,8 +4663,8 @@ "label": "Get real-time price quotation for a single Brazilian B3 stock. Returns th", "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L289", - "id": "controller_stocksapi_controller_rationale_289", + "source_location": "L307", + "id": "controller_stocksapi_controller_rationale_307", "community": 81, "norm_label": "get real-time price quotation for a single brazilian b3 stock. returns th" }, @@ -4764,7 +4773,7 @@ "source_file": "main/models/memory.py", "source_location": "L8", "id": "models_memory_orunmilamemory", - "community": 140, + "community": 45, "norm_label": "orunmilamemory" }, { @@ -4809,7 +4818,7 @@ "source_file": "main/models/sandbox.py", "source_location": "L5", "id": "models_sandbox_orunmilasandbox", - "community": 234, + "community": 140, "norm_label": "orunmilasandbox" }, { @@ -4926,7 +4935,7 @@ "source_file": "main/service/authentication_service.py", "source_location": "L1", "id": "main_service_authentication_service_py", - "community": 536, + "community": 569, "norm_label": "authentication_service.py" }, { @@ -4935,7 +4944,7 @@ "source_file": "main/service/authentication_service.py", "source_location": "L5", "id": "service_authentication_service_authenticationservice", - "community": 140, + "community": 45, "norm_label": "authenticationservice" }, { @@ -4944,7 +4953,7 @@ "source_file": "main/service/authentication_service.py", "source_location": "L7", "id": "service_authentication_service_initialize", - "community": 536, + "community": 569, "norm_label": "initialize()" }, { @@ -4953,7 +4962,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L1", "id": "main_service_orunmila_service_py", - "community": 605, + "community": 569, "norm_label": "orunmila_service.py" }, { @@ -4971,7 +4980,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L65", "id": "service_orunmila_service_orunmilaservice", - "community": 605, + "community": 569, "norm_label": "orunmilaservice" }, { @@ -4980,7 +4989,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L67", "id": "service_orunmila_service_initialize", - "community": 605, + "community": 569, "norm_label": "initialize()" }, { @@ -4989,7 +4998,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L1", "id": "main_service_scraper_service_py", - "community": 586, + "community": 21, "norm_label": "scraper_service.py" }, { @@ -4998,7 +5007,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L13", "id": "service_scraper_service_runscraper", - "community": 586, + "community": 21, "norm_label": "runscraper()" }, { @@ -5007,7 +5016,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L23", "id": "service_scraper_service_registerscraperjobs", - "community": 586, + "community": 21, "norm_label": "registerscraperjobs()" }, { @@ -5016,7 +5025,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L49", "id": "service_scraper_service_scraperservice", - "community": 586, + "community": 21, "norm_label": "scraperservice" }, { @@ -5025,7 +5034,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L51", "id": "service_scraper_service_initialize", - "community": 586, + "community": 21, "norm_label": "initialize()" }, { @@ -5088,7 +5097,7 @@ "source_file": "main/service/user_service.py", "source_location": "L1", "id": "main_service_user_service_py", - "community": 72, + "community": 536, "norm_label": "user_service.py" }, { @@ -5097,7 +5106,7 @@ "source_file": "main/service/user_service.py", "source_location": "L17", "id": "service_user_service_removeinactivesessions", - "community": 72, + "community": 536, "norm_label": "removeinactivesessions()" }, { @@ -5106,7 +5115,7 @@ "source_file": "main/service/user_service.py", "source_location": "L42", "id": "service_user_service_userservice", - "community": 72, + "community": 536, "norm_label": "userservice" }, { @@ -5115,7 +5124,7 @@ "source_file": "main/service/user_service.py", "source_location": "L44", "id": "service_user_service_initialize", - "community": 72, + "community": 536, "norm_label": "initialize()" }, { @@ -5124,7 +5133,7 @@ "source_file": "main/utils/connectivity.py", "source_location": "L1", "id": "main_utils_connectivity_py", - "community": 602, + "community": 523, "norm_label": "connectivity.py" }, { @@ -5133,7 +5142,7 @@ "source_file": "main/utils/connectivity.py", "source_location": "L11", "id": "utils_connectivity_checkdatabaseconnection", - "community": 602, + "community": 523, "norm_label": "checkdatabaseconnection()" }, { @@ -5151,7 +5160,7 @@ "source_file": "main/utils/errors.py", "source_location": "L1", "id": "main_utils_errors_py", - "community": 607, + "community": 572, "norm_label": "errors.py" }, { @@ -5187,7 +5196,7 @@ "source_file": "main/utils/errors.py", "source_location": "L26", "id": "utils_errors_builderrorresponse", - "community": 607, + "community": 572, "norm_label": "builderrorresponse()" }, { @@ -5196,7 +5205,7 @@ "source_file": "main/utils/errors.py", "source_location": "L36", "id": "utils_errors_httpexceptionhandler", - "community": 607, + "community": 572, "norm_label": "httpexceptionhandler()" }, { @@ -5205,7 +5214,7 @@ "source_file": "main/utils/errors.py", "source_location": "L43", "id": "utils_errors_validationexceptionhandler", - "community": 607, + "community": 572, "norm_label": "validationexceptionhandler()" }, { @@ -5214,7 +5223,7 @@ "source_file": "main/utils/errors.py", "source_location": "L55", "id": "utils_errors_genericexceptionhandler", - "community": 607, + "community": 572, "norm_label": "genericexceptionhandler()" }, { @@ -5304,7 +5313,7 @@ "source_file": "main/utils/migrator.py", "source_location": "L1", "id": "main_utils_migrator_py", - "community": 602, + "community": 523, "norm_label": "migrator.py" }, { @@ -5313,7 +5322,7 @@ "source_file": "main/utils/migrator.py", "source_location": "L8", "id": "utils_migrator_runmigrations", - "community": 602, + "community": 523, "norm_label": "runmigrations()" }, { @@ -5358,7 +5367,7 @@ "source_file": "main/utils/roles.py", "source_location": "L1", "id": "main_utils_roles_py", - "community": 523, + "community": 131, "norm_label": "roles.py" }, { @@ -5367,7 +5376,7 @@ "source_file": "main/utils/roles.py", "source_location": "L5", "id": "utils_roles_permission", - "community": 140, + "community": 45, "norm_label": "permission" }, { @@ -5376,7 +5385,7 @@ "source_file": "", "source_location": "", "id": "intflag", - "community": 491, + "community": 45, "norm_label": "intflag" }, { @@ -5394,7 +5403,7 @@ "source_file": "main/utils/roles.py", "source_location": "L17", "id": "utils_roles_roles", - "community": 491, + "community": 45, "norm_label": "roles" }, { @@ -5403,7 +5412,7 @@ "source_file": "main/utils/roles.py", "source_location": "L29", "id": "utils_roles_checkaccess", - "community": 523, + "community": 131, "norm_label": "checkaccess()" }, { @@ -5412,7 +5421,7 @@ "source_file": "main/utils/roles.py", "source_location": "L42", "id": "utils_roles_requirepermission", - "community": 523, + "community": 131, "norm_label": "requirepermission()" }, { @@ -5421,7 +5430,7 @@ "source_file": "main/utils/scheduler.py", "source_location": "L1", "id": "main_utils_scheduler_py", - "community": 72, + "community": 536, "norm_label": "scheduler.py" }, { @@ -5430,7 +5439,7 @@ "source_file": "main/utils/scheduler.py", "source_location": "L10", "id": "utils_scheduler_getsharedscheduler", - "community": 72, + "community": 536, "norm_label": "getsharedscheduler()" }, { @@ -5439,7 +5448,7 @@ "source_file": "main/utils/scheduler.py", "source_location": "L19", "id": "utils_scheduler_registerjob", - "community": 72, + "community": 536, "norm_label": "registerjob()" }, { @@ -5448,7 +5457,7 @@ "source_file": "main/utils/service_manager.py", "source_location": "L1", "id": "main_utils_service_manager_py", - "community": 536, + "community": 569, "norm_label": "service_manager.py" }, { @@ -5457,7 +5466,7 @@ "source_file": "main/utils/service_manager.py", "source_location": "L19", "id": "utils_service_manager_getapp", - "community": 536, + "community": 569, "norm_label": "getapp()" }, { @@ -5466,7 +5475,7 @@ "source_file": "main/utils/service_manager.py", "source_location": "L43", "id": "utils_service_manager_runall", - "community": 536, + "community": 569, "norm_label": "runall()" }, { @@ -5475,7 +5484,7 @@ "source_file": "main/utils/models/loader.py", "source_location": "L1", "id": "main_utils_models_loader_py", - "community": 605, + "community": 602, "norm_label": "loader.py" }, { @@ -5484,7 +5493,7 @@ "source_file": "main/utils/models/loader.py", "source_location": "L12", "id": "models_loader_getembeddingmodel", - "community": 605, + "community": 602, "norm_label": "getembeddingmodel()" }, { @@ -6055,10 +6064,19 @@ "norm_label": "architecture" }, { - "label": "Testing", + "label": "Code Style", "file_type": "document", "source_file": "AGENTS.md", "source_location": "L47", + "id": "server_agents_code_style", + "community": 153, + "norm_label": "code style" + }, + { + "label": "Testing", + "file_type": "document", + "source_file": "AGENTS.md", + "source_location": "L51", "id": "server_agents_testing", "community": 153, "norm_label": "testing" @@ -6067,7 +6085,7 @@ "label": "graphify", "file_type": "document", "source_file": "AGENTS.md", - "source_location": "L51", + "source_location": "L55", "id": "server_agents_graphify", "community": 153, "norm_label": "graphify" @@ -6076,7 +6094,7 @@ "label": "Swarm Delegation (default)", "file_type": "document", "source_file": "AGENTS.md", - "source_location": "L60", + "source_location": "L64", "id": "server_agents_swarm_delegation_default", "community": 153, "norm_label": "swarm delegation (default)" @@ -9696,7 +9714,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L166", "id": "plans_2026_09_04_wallet_management_task_2_alembic_migration_for_wallet_tables", - "community": 615, + "community": 132, "norm_label": "task 2: alembic migration for wallet tables" }, { @@ -9705,7 +9723,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L189", "id": "plans_2026_09_04_wallet_management_codeblock_6", - "community": 615, + "community": 132, "norm_label": "code:python (\"\"\"add wallet_holdings and wallet_lots tables)" }, { @@ -9714,7 +9732,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L248", "id": "plans_2026_09_04_wallet_management_codeblock_7", - "community": 615, + "community": 132, "norm_label": "code:python (import main.models.wallet)" }, { @@ -9723,7 +9741,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L262", "id": "plans_2026_09_04_wallet_management_codeblock_8", - "community": 615, + "community": 132, "norm_label": "code:bash (git add migrations/versions/wallet_tables_20260904_add_walle)" }, { @@ -9732,7 +9750,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L269", "id": "plans_2026_09_04_wallet_management_task_3_pure_derivation_math", - "community": 132, + "community": 618, "norm_label": "task 3: pure derivation math" }, { @@ -9741,7 +9759,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L281", "id": "plans_2026_09_04_wallet_management_codeblock_9", - "community": 132, + "community": 618, "norm_label": "code:python (from datetime import date)" }, { @@ -9750,7 +9768,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L325", "id": "plans_2026_09_04_wallet_management_codeblock_10", - "community": 132, + "community": 618, "norm_label": "code:python (from dataclasses import dataclass)" }, { @@ -9759,7 +9777,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L384", "id": "plans_2026_09_04_wallet_management_codeblock_11", - "community": 132, + "community": 618, "norm_label": "code:bash (git add main/app/wallet/__init__.py main/app/wallet/math.py )" }, { @@ -11940,6 +11958,168 @@ "community": 208, "norm_label": "10. plans and follow-ups" }, + { + "label": "Drop every cached endpoint body \u2014 called when the feather frame is replaced.", + "file_type": "rationale", + "source_file": "main/app/stocks_api/sync_cache.py", + "source_location": "L38", + "community": 562, + "norm_label": "drop every cached endpoint body \u2014 called when the feather frame is replaced.", + "id": "stocks_api_sync_cache_rationale_38" + }, + { + "label": "_runtimeConf()", + "file_type": "code", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L50", + "community": 82, + "norm_label": "_runtimeconf()", + "id": "stocks_api_build_runtimeconf" + }, + { + "label": "Feather build / read helpers for the stocks cache. Owns the on-disk layout (CAC", + "file_type": "rationale", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L1", + "community": 82, + "norm_label": "feather build / read helpers for the stocks cache. owns the on-disk layout (cac", + "id": "stocks_api_build_rationale_1" + }, + { + "label": "Return (engine, featherPath, nestedPath), preferring live values on the cach", + "file_type": "rationale", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L51", + "community": 82, + "norm_label": "return (engine, featherpath, nestedpath), preferring live values on the cach", + "id": "stocks_api_build_rationale_51" + }, + { + "label": "Abbreviation map for a frame (dependency-injected; no cache import). Result", + "file_type": "rationale", + "source_file": "main/app/stocks_api/compress.py", + "source_location": "L31", + "community": 194, + "norm_label": "abbreviation map for a frame (dependency-injected; no cache import). result", + "id": "stocks_api_compress_rationale_31" + }, + { + "label": "Nested-field map for a frame plus its nested sample (same memo policy).", + "file_type": "rationale", + "source_file": "main/app/stocks_api/compress.py", + "source_location": "L51", + "community": 194, + "norm_label": "nested-field map for a frame plus its nested sample (same memo policy).", + "id": "stocks_api_compress_rationale_51" + }, + { + "label": "Pure DataFrame helpers for the stocks feather cache (no I/O, no imports from sib", + "file_type": "rationale", + "source_file": "main/app/stocks_api/frame.py", + "source_location": "L1", + "community": 82, + "norm_label": "pure dataframe helpers for the stocks feather cache (no i/o, no imports from sib", + "id": "stocks_api_frame_rationale_1" + }, + { + "label": "Return (engine, featherPath, nestedPath), preferring live values on the cach", + "file_type": "rationale", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L47", + "community": 82, + "norm_label": "return (engine, featherpath, nestedpath), preferring live values on the cach", + "id": "stocks_api_build_rationale_47" + }, + { + "label": "Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret", + "file_type": "rationale", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L167", + "community": 157, + "norm_label": "get point-in-time fundamental/valuation data for brazilian b3 stocks. ret", + "id": "controller_stocksapi_controller_rationale_167" + }, + { + "label": "Get 10-year daily price history (cotation) for Brazilian B3 stocks. Retur", + "file_type": "rationale", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L235", + "community": 169, + "norm_label": "get 10-year daily price history (cotation) for brazilian b3 stocks. retur", + "id": "controller_stocksapi_controller_rationale_235" + }, + { + "label": "Get real-time price quotation for a single Brazilian B3 stock. Returns th", + "file_type": "rationale", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L289", + "community": 81, + "norm_label": "get real-time price quotation for a single brazilian b3 stock. returns th", + "id": "controller_stocksapi_controller_rationale_289" + }, + { + "label": "optimizeDtypes()", + "file_type": "code", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L43", + "community": 82, + "norm_label": "optimizedtypes()", + "id": "stocks_api_cache_optimizedtypes" + }, + { + "label": "arrowTypeFor()", + "file_type": "code", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L63", + "community": 82, + "norm_label": "arrowtypefor()", + "id": "stocks_api_cache_arrowtypefor" + }, + { + "label": "buildFeatherCache()", + "file_type": "code", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L80", + "community": 82, + "norm_label": "buildfeathercache()", + "id": "stocks_api_cache_buildfeathercache" + }, + { + "label": "tryBuildLock()", + "file_type": "code", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L171", + "community": 82, + "norm_label": "trybuildlock()", + "id": "stocks_api_cache_trybuildlock" + }, + { + "label": "sortCacheFrame()", + "file_type": "code", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L188", + "community": 82, + "norm_label": "sortcacheframe()", + "id": "stocks_api_cache_sortcacheframe" + }, + { + "label": "buildTickerIndex()", + "file_type": "code", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L198", + "community": 82, + "norm_label": "buildtickerindex()", + "id": "stocks_api_cache_buildtickerindex" + }, + { + "label": "readFeatherDataFrame()", + "file_type": "code", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L207", + "community": 82, + "norm_label": "readfeatherdataframe()", + "id": "stocks_api_cache_readfeatherdataframe" + }, { "label": "Priorities (active order, 2026-09-29)", "file_type": "document", @@ -13250,7 +13430,7 @@ "file_type": "code", "source_file": "main/utils/roles.py", "source_location": "L63", - "community": 523, + "community": 131, "norm_label": "_servicetoken()", "id": "utils_roles_servicetoken" }, @@ -13259,7 +13439,7 @@ "file_type": "code", "source_file": "main/utils/roles.py", "source_location": "L69", - "community": 523, + "community": 131, "norm_label": "_introspecturl()", "id": "utils_roles_introspecturl" }, @@ -13268,7 +13448,7 @@ "file_type": "code", "source_file": "main/utils/roles.py", "source_location": "L75", - "community": 523, + "community": 131, "norm_label": "_extractcredential()", "id": "utils_roles_extractcredential" }, @@ -13277,7 +13457,7 @@ "file_type": "code", "source_file": "main/utils/roles.py", "source_location": "L92", - "community": 523, + "community": 131, "norm_label": "introspectuser()", "id": "utils_roles_introspectuser" }, @@ -13286,7 +13466,7 @@ "file_type": "code", "source_file": "config.py", "source_location": "L59", - "community": 102, + "community": 586, "norm_label": "prometheussettings", "id": "server_config_prometheussettings" }, @@ -13466,7 +13646,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L35", - "community": 80, + "community": 53, "norm_label": "gettokenizer()", "id": "prometheus_compact_gettokenizer" }, @@ -13475,7 +13655,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L47", - "community": 80, + "community": 53, "norm_label": "counttokens()", "id": "prometheus_compact_counttokens" }, @@ -13754,7 +13934,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L35", - "community": 53, + "community": 621, "norm_label": "getmatrix()", "id": "prometheus_memory_getmatrix" }, @@ -13781,7 +13961,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L64", - "community": 140, + "community": 45, "norm_label": "memorycandidate", "id": "prometheus_memory_memorycandidate" }, @@ -13808,7 +13988,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L104", - "community": 53, + "community": 104, "norm_label": "minmax()", "id": "prometheus_memory_minmax" }, @@ -13817,7 +13997,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L113", - "community": 53, + "community": 63, "norm_label": "normalizekey()", "id": "prometheus_memory_normalizekey" }, @@ -13835,7 +14015,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L140", - "community": 53, + "community": 104, "norm_label": "scorerow()", "id": "prometheus_memory_scorerow" }, @@ -13844,7 +14024,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L152", - "community": 53, + "community": 104, "norm_label": "scorerecency()", "id": "prometheus_memory_scorerecency" }, @@ -13853,7 +14033,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L162", - "community": 53, + "community": 104, "norm_label": "scorecandidates()", "id": "prometheus_memory_scorecandidates" }, @@ -13916,7 +14096,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L286", - "community": 53, + "community": 104, "norm_label": "search()", "id": "prometheus_memory_search" }, @@ -13925,7 +14105,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L349", - "community": 53, + "community": 104, "norm_label": "fulltextsearch()", "id": "prometheus_memory_fulltextsearch" }, @@ -13934,7 +14114,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L407", - "community": 27, + "community": 53, "norm_label": "getusermemories()", "id": "prometheus_memory_getusermemories" }, @@ -14393,7 +14573,7 @@ "file_type": "code", "source_file": "main/app/prometheus/vector.py", "source_location": "L15", - "community": 53, + "community": 104, "norm_label": "embed()", "id": "prometheus_vector_embed" }, @@ -14609,7 +14789,7 @@ "file_type": "code", "source_file": "main/service/prometheus_service.py", "source_location": "L23", - "community": 518, + "community": 584, "norm_label": "memorymaintenance()", "id": "service_prometheus_service_memorymaintenance" }, @@ -15329,7 +15509,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L31", - "community": 53, + "community": 621, "norm_label": "matrixkey()", "id": "prometheus_memory_matrixkey" }, @@ -15338,7 +15518,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L38", - "community": 53, + "community": 621, "norm_label": "matrixusertag()", "id": "prometheus_memory_matrixusertag" }, @@ -15356,7 +15536,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/sync_cache.py", "source_location": "L13", - "community": 82, + "community": 562, "norm_label": "sync_cache()", "id": "stocks_api_sync_cache_sync_cache" }, @@ -15383,7 +15563,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L43", - "community": 53, + "community": 621, "norm_label": "getmatrixasync()", "id": "prometheus_memory_getmatrixasync" }, @@ -15419,7 +15599,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L333", - "community": 53, + "community": 104, "norm_label": "searchasync()", "id": "prometheus_memory_searchasync" }, @@ -15599,7 +15779,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L23", - "community": 222, + "community": 81, "norm_label": "jsonbytesresponse", "id": "controller_stocksapi_controller_jsonbytesresponse" }, @@ -15608,7 +15788,7 @@ "file_type": "code", "source_file": "", "source_location": "", - "community": 222, + "community": 81, "norm_label": "fastapiresponse", "id": "fastapiresponse" }, @@ -15617,7 +15797,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L26", - "community": 222, + "community": 81, "norm_label": ".render()", "id": "controller_stocksapi_controller_jsonbytesresponse_render" }, @@ -16409,7 +16589,7 @@ "file_type": "rationale", "source_file": "main/service/scraper_service.py", "source_location": "L23", - "community": 586, + "community": 21, "norm_label": "p5: register the scraper cron jobs on the shared scheduler. kept in this", "id": "service_scraper_service_rationale_23" }, @@ -16418,7 +16598,7 @@ "file_type": "code", "source_file": "main/service/user_service.py", "source_location": "L46", - "community": 72, + "community": 536, "norm_label": "registersessioncleanupjobs()", "id": "service_user_service_registersessioncleanupjobs" }, @@ -16427,7 +16607,7 @@ "file_type": "rationale", "source_file": "main/service/user_service.py", "source_location": "L47", - "community": 72, + "community": 536, "norm_label": "p5: register the session-cleanup job on the shared scheduler. kept in thi", "id": "service_user_service_rationale_47" }, @@ -17579,7 +17759,7 @@ "file_type": "rationale", "source_file": "main/utils/scheduler.py", "source_location": "L1", - "community": 72, + "community": 536, "norm_label": "p5: single shared backgroundscheduler for all services. replaces the 4 per-serv", "id": "utils_scheduler_rationale_1" }, @@ -17588,7 +17768,7 @@ "file_type": "rationale", "source_file": "main/utils/scheduler.py", "source_location": "L33", - "community": 72, + "community": 536, "norm_label": "return the process-wide scheduler, starting it on first use.", "id": "utils_scheduler_rationale_33" }, @@ -17597,7 +17777,7 @@ "file_type": "rationale", "source_file": "main/utils/scheduler.py", "source_location": "L43", - "community": 72, + "community": 536, "norm_label": "register func on the shared scheduler (replaces any same-id job). trigger i", "id": "utils_scheduler_rationale_43" }, @@ -17732,7 +17912,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L89", - "community": 608, + "community": 544, "norm_label": "fieldregistry", "id": "prometheus_compact_fieldregistry" }, @@ -17741,7 +17921,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L94", - "community": 608, + "community": 544, "norm_label": ".buildurl()", "id": "prometheus_compact_fieldregistry_buildurl" }, @@ -17750,7 +17930,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L99", - "community": 608, + "community": 544, "norm_label": ".fetchfields()", "id": "prometheus_compact_fieldregistry_fetchfields" }, @@ -17759,7 +17939,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L120", - "community": 608, + "community": 544, "norm_label": ".getfields()", "id": "prometheus_compact_fieldregistry_getfields" }, @@ -17768,7 +17948,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L127", - "community": 608, + "community": 544, "norm_label": ".buildmetricregex()", "id": "prometheus_compact_fieldregistry_buildmetricregex" }, @@ -17777,7 +17957,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L134", - "community": 608, + "community": 544, "norm_label": ".getmetricregex()", "id": "prometheus_compact_fieldregistry_getmetricregex" }, @@ -17930,7 +18110,7 @@ "file_type": "code", "source_file": "main/utils/service_manager.py", "source_location": "L15", - "community": 140, + "community": 45, "norm_label": "servicemanager", "id": "utils_service_manager_servicemanager" }, @@ -18290,7 +18470,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L139", - "community": 608, + "community": 544, "norm_label": ".invalidate()", "id": "prometheus_compact_fieldregistry_invalidate" }, @@ -18299,7 +18479,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L145", - "community": 608, + "community": 544, "norm_label": ".warmup()", "id": "prometheus_compact_fieldregistry_warmup" }, @@ -18308,7 +18488,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L153", - "community": 80, + "community": 53, "norm_label": "charcount()", "id": "prometheus_compact_charcount" }, @@ -18380,7 +18560,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L24", - "community": 222, + "community": 81, "norm_label": "sends pre-serialized json bytes without re-encoding (cache-friendly).", "id": "controller_stocksapi_controller_rationale_24" }, @@ -18479,7 +18659,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L51", - "community": 596, + "community": 63, "norm_label": ".set()", "id": "stocks_api_response_cache_responsecache_set" }, @@ -18524,7 +18704,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L323", - "community": 222, + "community": 26, "norm_label": "generatekey()", "id": "controller_stocksapi_controller_generatekey" }, @@ -19262,7 +19442,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L94", - "community": 608, + "community": 544, "norm_label": ".__new__()", "id": "prometheus_compact_fieldregistry_new" }, @@ -19352,7 +19532,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L46", - "community": 54, + "community": 82, "norm_label": "rebuildabbrevs()", "id": "stocks_api_compressor_rebuildabbrevs" }, @@ -20576,7 +20756,7 @@ "file_type": "code", "source_file": "main/utils/connectivity.py", "source_location": "L13", - "community": 602, + "community": 523, "norm_label": "checksingledb()", "id": "utils_connectivity_checksingledb" }, @@ -22502,7 +22682,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/util.py", "source_location": "L27", - "community": 596, + "community": 73, "norm_label": "_parse_date()", "id": "stocks_api_util_parse_date" }, @@ -22718,7 +22898,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/util.py", "source_location": "L39", - "community": 596, + "community": 73, "norm_label": "parsedatestart()", "id": "stocks_api_util_parsedatestart" }, @@ -22727,7 +22907,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/util.py", "source_location": "L43", - "community": 596, + "community": 73, "norm_label": "parsedateend()", "id": "stocks_api_util_parsedateend" }, @@ -28046,7 +28226,7 @@ "file_type": "code", "source_file": "tests/conftest.py", "source_location": "L81", - "community": 251, + "community": 535, "norm_label": "stocks_http_client()", "id": "tests_conftest_stocks_http_client" }, @@ -28055,7 +28235,7 @@ "file_type": "code", "source_file": "tests/conftest.py", "source_location": "L106", - "community": 251, + "community": 535, "norm_label": "client()", "id": "tests_conftest_client" }, @@ -28082,7 +28262,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L82", - "community": 251, + "community": 535, "norm_label": "testclient with stocks router + verifyapikey + getcurrentuser overrides.", "id": "tests_conftest_rationale_82" }, @@ -28091,7 +28271,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L107", - "community": 251, + "community": 535, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_107" }, @@ -28199,7 +28379,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L7", - "community": 8, + "community": 504, "norm_label": "testbuildsystempromptstate", "id": "tests_test_agent_state_integration_testbuildsystempromptstate" }, @@ -28208,7 +28388,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L8", - "community": 8, + "community": 504, "norm_label": ".test_build_system_prompt_no_state()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_no_state" }, @@ -28217,7 +28397,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L13", - "community": 8, + "community": 504, "norm_label": ".test_build_system_prompt_with_state()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_with_state" }, @@ -28226,7 +28406,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L21", - "community": 8, + "community": 504, "norm_label": ".test_build_system_prompt_empty_state()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_empty_state" }, @@ -28235,7 +28415,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L27", - "community": 8, + "community": 504, "norm_label": ".test_build_system_prompt_state_after_memories()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_state_after_memories" }, @@ -28244,7 +28424,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L37", - "community": 8, + "community": 504, "norm_label": ".test_build_system_prompt_multiple_state_entries()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_multiple_state_entries" }, @@ -28325,7 +28505,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L9", - "community": 8, + "community": 504, "norm_label": "system prompt should work without state parameter.", "id": "tests_test_agent_state_integration_rationale_9" }, @@ -28334,7 +28514,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L14", - "community": 8, + "community": 504, "norm_label": "system prompt should include state context when provided.", "id": "tests_test_agent_state_integration_rationale_14" }, @@ -28343,7 +28523,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L22", - "community": 8, + "community": 504, "norm_label": "system prompt should not include state section when empty.", "id": "tests_test_agent_state_integration_rationale_22" }, @@ -28352,7 +28532,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L28", - "community": 8, + "community": 504, "norm_label": "state section should appear after memories section.", "id": "tests_test_agent_state_integration_rationale_28" }, @@ -28361,7 +28541,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L38", - "community": 8, + "community": 504, "norm_label": "all state entries should appear in the prompt.", "id": "tests_test_agent_state_integration_rationale_38" }, @@ -28415,7 +28595,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L1", - "community": 504, + "community": 604, "norm_label": "test_api_key_quota_atomic.py", "id": "tests_test_api_key_quota_atomic_py" }, @@ -28424,7 +28604,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L18", - "community": 504, + "community": 604, "norm_label": "samplekeydata()", "id": "tests_test_api_key_quota_atomic_samplekeydata" }, @@ -28478,7 +28658,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L150", - "community": 572, + "community": 608, "norm_label": ".test_invalid_api_key_returns_zero_rows()", "id": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_invalid_api_key_returns_zero_rows" }, @@ -28487,7 +28667,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L164", - "community": 572, + "community": 608, "norm_label": ".test_multiple_keys_independent_quotas()", "id": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_multiple_keys_independent_quotas" }, @@ -28559,7 +28739,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L1", - "community": 504, + "community": 604, "norm_label": "tests for atomic api key quota enforcement (race condition fix). verifies tha", "id": "tests_test_api_key_quota_atomic_rationale_1" }, @@ -28568,7 +28748,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L19", - "community": 504, + "community": 604, "norm_label": "sample api key data for tests.", "id": "tests_test_api_key_quota_atomic_rationale_19" }, @@ -28622,7 +28802,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L151", - "community": 572, + "community": 608, "norm_label": "test that invalid api key returns zero rows affected.", "id": "tests_test_api_key_quota_atomic_rationale_151" }, @@ -28631,7 +28811,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L165", - "community": 572, + "community": 608, "norm_label": "test that multiple api keys have independent quotas.", "id": "tests_test_api_key_quota_atomic_rationale_165" }, @@ -28703,7 +28883,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L1", - "community": 606, + "community": 560, "norm_label": "test_auth_util.py", "id": "tests_test_auth_util_py" }, @@ -28802,7 +28982,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L69", - "community": 606, + "community": 560, "norm_label": "testsessionexpiryconfig", "id": "tests_test_auth_util_testsessionexpiryconfig" }, @@ -28811,7 +28991,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L70", - "community": 606, + "community": 560, "norm_label": ".test_session_expiry_days_is_30()", "id": "tests_test_auth_util_testsessionexpiryconfig_test_session_expiry_days_is_30" }, @@ -28820,7 +29000,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L73", - "community": 606, + "community": 560, "norm_label": ".test_session_expiry_hours_calculation()", "id": "tests_test_auth_util_testsessionexpiryconfig_test_session_expiry_hours_calculation" }, @@ -28829,7 +29009,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L78", - "community": 606, + "community": 560, "norm_label": ".test_default_token_expiry_equals_30_days()", "id": "tests_test_auth_util_testsessionexpiryconfig_test_default_token_expiry_equals_30_days" }, @@ -28892,7 +29072,7 @@ "file_type": "code", "source_file": "tests/test_config.py", "source_location": "L1", - "community": 102, + "community": 586, "norm_label": "test_config.py", "id": "tests_test_config_py" }, @@ -28901,7 +29081,7 @@ "file_type": "code", "source_file": "tests/test_config.py", "source_location": "L5", - "community": 102, + "community": 586, "norm_label": "testconfig", "id": "tests_test_config_testconfig" }, @@ -28919,7 +29099,7 @@ "file_type": "code", "source_file": "tests/test_config.py", "source_location": "L12", - "community": 102, + "community": 586, "norm_label": ".test_prometheus_getitem()", "id": "tests_test_config_testconfig_test_prometheus_getitem" }, @@ -28937,7 +29117,7 @@ "file_type": "code", "source_file": "tests/test_config.py", "source_location": "L22", - "community": 102, + "community": 586, "norm_label": ".test_base_mansa_settings_get()", "id": "tests_test_config_testconfig_test_base_mansa_settings_get" }, @@ -28955,7 +29135,7 @@ "file_type": "code", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L8", - "community": 618, + "community": 624, "norm_label": "testcheckmysqlconnection", "id": "tests_test_connectivity_coverage_testcheckmysqlconnection" }, @@ -29045,7 +29225,7 @@ "file_type": "code", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L114", - "community": 617, + "community": 623, "norm_label": "testcheckserviceconnection", "id": "tests_test_connectivity_coverage_testcheckserviceconnection" }, @@ -29135,7 +29315,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L9", - "community": 618, + "community": 624, "norm_label": "checkmysqlconnection \u2014 success, errors, engine=none paths.", "id": "tests_test_connectivity_coverage_rationale_9" }, @@ -29144,7 +29324,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L115", - "community": 617, + "community": 623, "norm_label": "checkserviceconnection \u2014 success, not found, errors.", "id": "tests_test_connectivity_coverage_rationale_115" }, @@ -29180,7 +29360,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L57", - "community": 120, + "community": 99, "norm_label": "_make_prometheus_client()", "id": "tests_test_controllers_coverage_make_prometheus_client" }, @@ -29234,7 +29414,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L130", - "community": 491, + "community": 45, "norm_label": "testhealthendpoint", "id": "tests_test_controllers_coverage_testhealthendpoint" }, @@ -29243,7 +29423,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L133", - "community": 491, + "community": 45, "norm_label": ".test_health_returns_ok()", "id": "tests_test_controllers_coverage_testhealthendpoint_test_health_returns_ok" }, @@ -29252,7 +29432,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L146", - "community": 120, + "community": 45, "norm_label": "testregisterendpoint", "id": "tests_test_controllers_coverage_testregisterendpoint" }, @@ -29297,7 +29477,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L215", - "community": 120, + "community": 45, "norm_label": "testloginendpoint", "id": "tests_test_controllers_coverage_testloginendpoint" }, @@ -29324,7 +29504,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L257", - "community": 120, + "community": 45, "norm_label": "testlogoutendpoint", "id": "tests_test_controllers_coverage_testlogoutendpoint" }, @@ -29387,7 +29567,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L344", - "community": 491, + "community": 45, "norm_label": "testgooglelogin", "id": "tests_test_controllers_coverage_testgooglelogin" }, @@ -29414,7 +29594,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L390", - "community": 120, + "community": 45, "norm_label": "testgooglecallback", "id": "tests_test_controllers_coverage_testgooglecallback" }, @@ -29621,7 +29801,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L727", - "community": 136, + "community": 120, "norm_label": "testrevokesession", "id": "tests_test_controllers_coverage_testrevokesession" }, @@ -29630,7 +29810,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L730", - "community": 136, + "community": 120, "norm_label": ".test_revoke_session_success()", "id": "tests_test_controllers_coverage_testrevokesession_test_revoke_session_success" }, @@ -29639,7 +29819,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L757", - "community": 136, + "community": 120, "norm_label": ".test_revoke_session_not_found()", "id": "tests_test_controllers_coverage_testrevokesession_test_revoke_session_not_found" }, @@ -29648,7 +29828,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L779", - "community": 136, + "community": 120, "norm_label": ".test_revoke_session_failure()", "id": "tests_test_controllers_coverage_testrevokesession_test_revoke_session_failure" }, @@ -29675,7 +29855,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L835", - "community": 610, + "community": 45, "norm_label": "testprometheushealth", "id": "tests_test_controllers_coverage_testprometheushealth" }, @@ -29684,7 +29864,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L838", - "community": 610, + "community": 45, "norm_label": ".test_health()", "id": "tests_test_controllers_coverage_testprometheushealth_test_health" }, @@ -29693,7 +29873,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L849", - "community": 45, + "community": 99, "norm_label": "testprometheusgetsessions", "id": "tests_test_controllers_coverage_testprometheusgetsessions" }, @@ -29702,7 +29882,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L852", - "community": 45, + "community": 99, "norm_label": ".test_get_sessions()", "id": "tests_test_controllers_coverage_testprometheusgetsessions_test_get_sessions" }, @@ -29711,7 +29891,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L867", - "community": 45, + "community": 99, "norm_label": "testprometheuscreatesession", "id": "tests_test_controllers_coverage_testprometheuscreatesession" }, @@ -29720,7 +29900,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L870", - "community": 45, + "community": 99, "norm_label": ".test_create_session()", "id": "tests_test_controllers_coverage_testprometheuscreatesession_test_create_session" }, @@ -29792,7 +29972,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L997", - "community": 584, + "community": 99, "norm_label": "testprometheusdeletesession", "id": "tests_test_controllers_coverage_testprometheusdeletesession" }, @@ -29801,7 +29981,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1000", - "community": 584, + "community": 99, "norm_label": ".test_delete_session_success()", "id": "tests_test_controllers_coverage_testprometheusdeletesession_test_delete_session_success" }, @@ -29810,7 +29990,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1010", - "community": 584, + "community": 99, "norm_label": ".test_delete_session_not_found()", "id": "tests_test_controllers_coverage_testprometheusdeletesession_test_delete_session_not_found" }, @@ -29855,7 +30035,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1121", - "community": 148, + "community": 99, "norm_label": ".test_chat_generic_exception()", "id": "tests_test_controllers_coverage_testprometheuschat_test_chat_generic_exception" }, @@ -29864,7 +30044,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1144", - "community": 511, + "community": 605, "norm_label": "teststocksapihealth", "id": "tests_test_controllers_coverage_teststocksapihealth" }, @@ -29873,7 +30053,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1147", - "community": 511, + "community": 605, "norm_label": ".test_health()", "id": "tests_test_controllers_coverage_teststocksapihealth_test_health" }, @@ -29936,7 +30116,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1202", - "community": 609, + "community": 14, "norm_label": ".test_generate_key_admin_bypasses_permission_check()", "id": "tests_test_controllers_coverage_teststocksapigeneratekey_test_generate_key_admin_bypasses_permission_check" }, @@ -29945,7 +30125,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1214", - "community": 609, + "community": 14, "norm_label": ".test_generate_key_exception()", "id": "tests_test_controllers_coverage_teststocksapigeneratekey_test_generate_key_exception" }, @@ -29972,7 +30152,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1249", - "community": 588, + "community": 493, "norm_label": ".test_add_role_already_has_role()", "id": "tests_test_controllers_coverage_testaddroletouser_test_add_role_already_has_role" }, @@ -30008,7 +30188,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1282", - "community": 578, + "community": 493, "norm_label": ".test_get_current_user_valid_session()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_valid_session" }, @@ -30017,7 +30197,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1307", - "community": 592, + "community": 493, "norm_label": ".test_get_current_user_session_revoked()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_session_revoked" }, @@ -30035,7 +30215,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1340", - "community": 544, + "community": 493, "norm_label": ".test_get_current_user_generic_exception()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_generic_exception" }, @@ -30044,7 +30224,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1357", - "community": 560, + "community": 493, "norm_label": ".test_get_current_user_no_session_id()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_no_session_id" }, @@ -30161,7 +30341,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L58", - "community": 120, + "community": 99, "norm_label": "return (client, app) with prometheus router and mocked deps.", "id": "tests_test_controllers_coverage_rationale_58" }, @@ -30188,7 +30368,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L131", - "community": 491, + "community": 45, "norm_label": "covers line 28: get /auth/health.", "id": "tests_test_controllers_coverage_rationale_131" }, @@ -30197,7 +30377,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L147", - "community": 120, + "community": 45, "norm_label": "covers lines 44-54, 63, 66-71: register success, valueerror, generic exception.", "id": "tests_test_controllers_coverage_rationale_147" }, @@ -30242,7 +30422,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L216", - "community": 120, + "community": 45, "norm_label": "covers lines 87-93, 102: login success and failure paths.", "id": "tests_test_controllers_coverage_rationale_216" }, @@ -30269,7 +30449,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L258", - "community": 120, + "community": 45, "norm_label": "covers lines 107, 109-130, 133: logout token extraction and revocation.", "id": "tests_test_controllers_coverage_rationale_258" }, @@ -30287,7 +30467,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L281", - "community": 120, + "community": 45, "norm_label": "covers lines 111-113: token extracted from authorization bearer header.", "id": "tests_test_controllers_coverage_rationale_281" }, @@ -30332,7 +30512,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L345", - "community": 491, + "community": 45, "norm_label": "covers lines 139, 141-149: googlelogin endpoint.", "id": "tests_test_controllers_coverage_rationale_345" }, @@ -30359,7 +30539,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L391", - "community": 120, + "community": 45, "norm_label": "covers lines 155-156, 158, 160-168, 170-177, 179-184, 186, 190-204: googlecallba", "id": "tests_test_controllers_coverage_rationale_391" }, @@ -30494,7 +30674,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L728", - "community": 136, + "community": 120, "norm_label": "covers lines 126-136: delete /user/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_728" }, @@ -30503,7 +30683,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L731", - "community": 136, + "community": 120, "norm_label": "covers lines 126, 131, 135-136.", "id": "tests_test_controllers_coverage_rationale_731" }, @@ -30512,7 +30692,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L758", - "community": 136, + "community": 120, "norm_label": "covers lines 127-129: session not found.", "id": "tests_test_controllers_coverage_rationale_758" }, @@ -30521,7 +30701,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L780", - "community": 136, + "community": 120, "norm_label": "covers lines 132-133: revokesession returns false.", "id": "tests_test_controllers_coverage_rationale_780" }, @@ -30548,7 +30728,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L836", - "community": 610, + "community": 45, "norm_label": "covers line 24: get /prometheus/health.", "id": "tests_test_controllers_coverage_rationale_836" }, @@ -30557,7 +30737,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L850", - "community": 45, + "community": 99, "norm_label": "covers lines 33-36: get /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_850" }, @@ -30566,7 +30746,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L868", - "community": 45, + "community": 99, "norm_label": "covers line 52: post /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_868" }, @@ -30638,7 +30818,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L998", - "community": 584, + "community": 99, "norm_label": "covers lines 95-98: delete /prometheus/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_998" }, @@ -30647,7 +30827,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1001", - "community": 584, + "community": 99, "norm_label": "covers lines 95-98: session deleted.", "id": "tests_test_controllers_coverage_rationale_1001" }, @@ -30656,7 +30836,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1011", - "community": 584, + "community": 99, "norm_label": "covers lines 96-97: session not found.", "id": "tests_test_controllers_coverage_rationale_1011" }, @@ -30701,7 +30881,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1122", - "community": 148, + "community": 99, "norm_label": "generic exception in chat propagates via sse error event.", "id": "tests_test_controllers_coverage_rationale_1122" }, @@ -30710,7 +30890,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1145", - "community": 511, + "community": 605, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1145" }, @@ -30755,7 +30935,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1203", - "community": 609, + "community": 14, "norm_label": "covers lines 57-60: admin bypasses permission check and generates key.", "id": "tests_test_controllers_coverage_rationale_1203" }, @@ -30764,7 +30944,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1215", - "community": 609, + "community": 14, "norm_label": "covers lines 61-63: exception during key generation (admin path).", "id": "tests_test_controllers_coverage_rationale_1215" }, @@ -30791,7 +30971,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1250", - "community": 588, + "community": 493, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1250" }, @@ -30809,7 +30989,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1276", - "community": 578, + "community": 493, "norm_label": "covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: usermanager.getc", "id": "tests_test_controllers_coverage_rationale_1276" }, @@ -30818,7 +30998,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1283", - "community": 578, + "community": 493, "norm_label": "covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval.", "id": "tests_test_controllers_coverage_rationale_1283" }, @@ -30827,7 +31007,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1308", - "community": 592, + "community": 493, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1308" }, @@ -30845,7 +31025,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1341", - "community": 544, + "community": 493, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1341" }, @@ -30854,7 +31034,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1358", - "community": 560, + "community": 493, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1358" }, @@ -31493,7 +31673,7 @@ "file_type": "code", "source_file": "tests/test_error_handlers.py", "source_location": "L25", - "community": 33, + "community": 120, "norm_label": "app()", "id": "tests_test_error_handlers_app" }, @@ -31781,7 +31961,7 @@ "file_type": "code", "source_file": "tests/test_harness_state.py", "source_location": "L1", - "community": 93, + "community": 586, "norm_label": "test_harness_state.py", "id": "tests_test_harness_state_py" }, @@ -31943,7 +32123,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L14", - "community": 25, + "community": 607, "norm_label": "testregistervalidation", "id": "tests_test_input_validation_testregistervalidation" }, @@ -31952,7 +32132,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L17", - "community": 25, + "community": 607, "norm_label": ".test_valid_registration()", "id": "tests_test_input_validation_testregistervalidation_test_valid_registration" }, @@ -31961,7 +32141,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L25", - "community": 25, + "community": 607, "norm_label": ".test_username_too_short()", "id": "tests_test_input_validation_testregistervalidation_test_username_too_short" }, @@ -31970,7 +32150,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L32", - "community": 25, + "community": 607, "norm_label": ".test_username_too_long()", "id": "tests_test_input_validation_testregistervalidation_test_username_too_long" }, @@ -31979,7 +32159,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L39", - "community": 25, + "community": 607, "norm_label": ".test_email_too_short()", "id": "tests_test_input_validation_testregistervalidation_test_email_too_short" }, @@ -31988,7 +32168,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L46", - "community": 25, + "community": 607, "norm_label": ".test_password_too_short()", "id": "tests_test_input_validation_testregistervalidation_test_password_too_short" }, @@ -31997,7 +32177,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L54", - "community": 25, + "community": 610, "norm_label": "testloginvalidation", "id": "tests_test_input_validation_testloginvalidation" }, @@ -32006,7 +32186,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L57", - "community": 25, + "community": 610, "norm_label": ".test_valid_login_payload()", "id": "tests_test_input_validation_testloginvalidation_test_valid_login_payload" }, @@ -32015,7 +32195,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L65", - "community": 25, + "community": 610, "norm_label": ".test_username_too_short()", "id": "tests_test_input_validation_testloginvalidation_test_username_too_short" }, @@ -32024,7 +32204,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L72", - "community": 25, + "community": 610, "norm_label": ".test_password_too_short()", "id": "tests_test_input_validation_testloginvalidation_test_password_too_short" }, @@ -32096,7 +32276,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L129", - "community": 25, + "community": 609, "norm_label": "testchatvalidation", "id": "tests_test_input_validation_testchatvalidation" }, @@ -32105,7 +32285,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L132", - "community": 25, + "community": 609, "norm_label": ".test_empty_text()", "id": "tests_test_input_validation_testchatvalidation_test_empty_text" }, @@ -32114,7 +32294,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L140", - "community": 25, + "community": 609, "norm_label": ".test_text_too_long()", "id": "tests_test_input_validation_testchatvalidation_test_text_too_long" }, @@ -32123,7 +32303,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L148", - "community": 25, + "community": 609, "norm_label": ".test_max_length_boundary()", "id": "tests_test_input_validation_testchatvalidation_test_max_length_boundary" }, @@ -32177,7 +32357,7 @@ "file_type": "rationale", "source_file": "tests/test_input_validation.py", "source_location": "L15", - "community": 25, + "community": 607, "norm_label": "post /auth/register \u2014 validates username, email, password via body(...)", "id": "tests_test_input_validation_rationale_15" }, @@ -32186,7 +32366,7 @@ "file_type": "rationale", "source_file": "tests/test_input_validation.py", "source_location": "L55", - "community": 25, + "community": 610, "norm_label": "post /auth/login \u2014 validates username, password via body(...)", "id": "tests_test_input_validation_rationale_55" }, @@ -32213,7 +32393,7 @@ "file_type": "rationale", "source_file": "tests/test_input_validation.py", "source_location": "L130", - "community": 25, + "community": 609, "norm_label": "post /prometheus/chat/stream \u2014 validates query via body(...)", "id": "tests_test_input_validation_rationale_130" }, @@ -32330,7 +32510,7 @@ "file_type": "code", "source_file": "tests/test_logging_config_coverage.py", "source_location": "L103", - "community": 122, + "community": 599, "norm_label": "testsetuplogging", "id": "tests_test_logging_config_coverage_testsetuplogging" }, @@ -32375,7 +32555,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L8", - "community": 474, + "community": 140, "norm_label": "_create_memory()", "id": "tests_test_memory_dedup_create_memory" }, @@ -32384,7 +32564,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L12", - "community": 474, + "community": 140, "norm_label": "_count_memories()", "id": "tests_test_memory_dedup_count_memories" }, @@ -32393,7 +32573,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L20", - "community": 474, + "community": 140, "norm_label": "_get_memory()", "id": "tests_test_memory_dedup_get_memory" }, @@ -32411,7 +32591,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L29", - "community": 474, + "community": 140, "norm_label": ".test_exact_same_key_updates()", "id": "tests_test_memory_dedup_testexactsamekeyupdates_test_exact_same_key_updates" }, @@ -32429,7 +32609,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L37", - "community": 474, + "community": 140, "norm_label": ".test_similar_key_merges()", "id": "tests_test_memory_dedup_testsimilarkeymerges_test_similar_key_merges" }, @@ -32447,7 +32627,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L47", - "community": 474, + "community": 140, "norm_label": ".test_different_keys_no_merge()", "id": "tests_test_memory_dedup_testdifferentkeysnomerge_test_different_keys_no_merge" }, @@ -32465,7 +32645,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L56", - "community": 474, + "community": 140, "norm_label": ".test_merge_boosts_score()", "id": "tests_test_memory_dedup_testmergeboostsscore_test_merge_boosts_score" }, @@ -32483,7 +32663,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L65", - "community": 474, + "community": 140, "norm_label": ".test_merge_increments_access()", "id": "tests_test_memory_dedup_testmergeincrementsaccess_test_merge_increments_access" }, @@ -32501,7 +32681,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L74", - "community": 474, + "community": 140, "norm_label": ".test_threshold_boundary()", "id": "tests_test_memory_dedup_testthresholdboundary_test_threshold_boundary" }, @@ -32510,7 +32690,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L38", - "community": 474, + "community": 140, "norm_label": "keys with jaccard > 0.8 should merge.", "id": "tests_test_memory_dedup_rationale_38" }, @@ -32519,7 +32699,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L48", - "community": 474, + "community": 140, "norm_label": "keys with low similarity should not merge.", "id": "tests_test_memory_dedup_rationale_48" }, @@ -32528,7 +32708,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L75", - "community": 474, + "community": 140, "norm_label": "keys with jaccard <= 0.8 should not merge.", "id": "tests_test_memory_dedup_rationale_75" }, @@ -32627,7 +32807,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L85", - "community": 518, + "community": 614, "norm_label": ".test_dead_memory_archived()", "id": "tests_test_memory_maintenance_testarchive_test_dead_memory_archived" }, @@ -32636,7 +32816,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L92", - "community": 518, + "community": 617, "norm_label": ".test_low_score_but_recent_not_archived()", "id": "tests_test_memory_maintenance_testarchive_test_low_score_but_recent_not_archived" }, @@ -32654,7 +32834,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L106", - "community": 518, + "community": 613, "norm_label": ".test_accessed_memory_not_archived()", "id": "tests_test_memory_maintenance_testarchive_test_accessed_memory_not_archived" }, @@ -32681,7 +32861,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L133", - "community": 518, + "community": 592, "norm_label": "testdecayandarchivetogether", "id": "tests_test_memory_maintenance_testdecayandarchivetogether" }, @@ -32690,7 +32870,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L134", - "community": 518, + "community": 592, "norm_label": ".test_decay_then_archive_check()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_decay_then_archive_check" }, @@ -32699,7 +32879,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L143", - "community": 518, + "community": 592, "norm_label": ".test_score_above_threshold_after_decay_not_archived()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_score_above_threshold_after_decay_not_archived" }, @@ -32708,7 +32888,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L150", - "community": 518, + "community": 592, "norm_label": ".test_score_just_below_threshold_archived()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_score_just_below_threshold_archived" }, @@ -32717,7 +32897,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L156", - "community": 518, + "community": 592, "norm_label": ".test_days_just_below_threshold_not_archived()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_days_just_below_threshold_not_archived" }, @@ -32726,7 +32906,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L163", - "community": 518, + "community": 592, "norm_label": ".test_days_just_above_threshold_archived()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_days_just_above_threshold_archived" }, @@ -32744,7 +32924,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L171", - "community": 518, + "community": 584, "norm_label": ".test_no_memories_does_not_crash()", "id": "tests_test_memory_maintenance_testemptydatabase_test_no_memories_does_not_crash" }, @@ -32780,7 +32960,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L86", - "community": 518, + "community": 614, "norm_label": "score below threshold + accesscount=0 + 90+ days \u2192 archived.", "id": "tests_test_memory_maintenance_rationale_86" }, @@ -32789,7 +32969,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L93", - "community": 518, + "community": 617, "norm_label": "low score but accessed recently \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_93" }, @@ -32807,7 +32987,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L107", - "community": 518, + "community": 613, "norm_label": "even with low score, if accessed \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_107" }, @@ -32825,7 +33005,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L135", - "community": 518, + "community": 592, "norm_label": "decay happens first, then archive check with new scores.", "id": "tests_test_memory_maintenance_rationale_135" }, @@ -32834,7 +33014,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L144", - "community": 518, + "community": 592, "norm_label": "score that decays to >= threshold stays alive. 0.12 * 0.90 = 0.108 >= 0.1.", "id": "tests_test_memory_maintenance_rationale_144" }, @@ -32843,7 +33023,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L157", - "community": 518, + "community": 592, "norm_label": "89 days with low score \u2192 not archived (need > 90).", "id": "tests_test_memory_maintenance_rationale_157" }, @@ -33176,7 +33356,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L64", - "community": 614, + "community": 615, "norm_label": "testtoolregistry", "id": "tests_test_memory_tools_wiring_testtoolregistry" }, @@ -33185,7 +33365,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L67", - "community": 614, + "community": 615, "norm_label": ".test_registry_contains_memory_tools()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_contains_memory_tools" }, @@ -33194,7 +33374,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L71", - "community": 614, + "community": 615, "norm_label": ".test_registry_values_are_callable()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_values_are_callable" }, @@ -33203,7 +33383,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L75", - "community": 614, + "community": 615, "norm_label": ".test_registry_matches_tool_names()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_matches_tool_names" }, @@ -33230,7 +33410,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L112", - "community": 589, + "community": 529, "norm_label": "testdispatchroutesmemorytools", "id": "tests_test_memory_tools_wiring_testdispatchroutesmemorytools" }, @@ -33284,7 +33464,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L65", - "community": 614, + "community": 615, "norm_label": "tool_registry pattern must work correctly.", "id": "tests_test_memory_tools_wiring_rationale_65" }, @@ -33302,7 +33482,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L113", - "community": 589, + "community": 529, "norm_label": "dispatchtoolcall must route memory tool names via tool_registry.", "id": "tests_test_memory_tools_wiring_rationale_113" }, @@ -33860,7 +34040,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L1", - "community": 482, + "community": 186, "norm_label": "test_pagination.py", "id": "tests_test_pagination_py" }, @@ -33869,7 +34049,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L14", - "community": 482, + "community": 186, "norm_label": "app()", "id": "tests_test_pagination_app" }, @@ -33878,7 +34058,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L35", - "community": 482, + "community": 186, "norm_label": "client()", "id": "tests_test_pagination_client" }, @@ -33977,7 +34157,7 @@ "file_type": "rationale", "source_file": "tests/test_pagination.py", "source_location": "L1", - "community": 482, + "community": 186, "norm_label": "tests for inline pagination params (used in user + prometheus controllers).", "id": "tests_test_pagination_rationale_1" }, @@ -35219,7 +35399,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L1", - "community": 600, + "community": 511, "norm_label": "test_request_id.py", "id": "tests_test_request_id_py" }, @@ -35228,7 +35408,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L14", - "community": 600, + "community": 511, "norm_label": "app()", "id": "tests_test_request_id_app" }, @@ -35237,7 +35417,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L30", - "community": 600, + "community": 511, "norm_label": "client()", "id": "tests_test_request_id_client" }, @@ -35246,7 +35426,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L34", - "community": 600, + "community": 511, "norm_label": "testrequestidmiddleware", "id": "tests_test_request_id_testrequestidmiddleware" }, @@ -35255,7 +35435,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L35", - "community": 600, + "community": 511, "norm_label": ".test_generates_uuid_when_no_header()", "id": "tests_test_request_id_testrequestidmiddleware_test_generates_uuid_when_no_header" }, @@ -35264,7 +35444,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L44", - "community": 600, + "community": 511, "norm_label": ".test_returns_generated_uuid_in_body()", "id": "tests_test_request_id_testrequestidmiddleware_test_returns_generated_uuid_in_body" }, @@ -35273,7 +35453,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L51", - "community": 600, + "community": 511, "norm_label": ".test_uses_client_provided_request_id()", "id": "tests_test_request_id_testrequestidmiddleware_test_uses_client_provided_request_id" }, @@ -35282,7 +35462,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L57", - "community": 600, + "community": 511, "norm_label": ".test_response_header_matches_request()", "id": "tests_test_request_id_testrequestidmiddleware_test_response_header_matches_request" }, @@ -35291,7 +35471,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L62", - "community": 600, + "community": 511, "norm_label": ".test_different_requests_get_different_ids()", "id": "tests_test_request_id_testrequestidmiddleware_test_different_requests_get_different_ids" }, @@ -35300,7 +35480,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L67", - "community": 600, + "community": 511, "norm_label": ".test_context_var_available_in_route()", "id": "tests_test_request_id_testrequestidmiddleware_test_context_var_available_in_route" }, @@ -35309,7 +35489,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L72", - "community": 600, + "community": 511, "norm_label": ".test_empty_x_request_id_header_generates_uuid()", "id": "tests_test_request_id_testrequestidmiddleware_test_empty_x_request_id_header_generates_uuid" }, @@ -35318,7 +35498,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L81", - "community": 600, + "community": 511, "norm_label": ".test_middleware_preserves_response_body()", "id": "tests_test_request_id_testrequestidmiddleware_test_middleware_preserves_response_body" }, @@ -35651,7 +35831,7 @@ "file_type": "code", "source_file": "tests/test_roles_coverage.py", "source_location": "L83", - "community": 491, + "community": 45, "norm_label": "testpermissionall", "id": "tests_test_roles_coverage_testpermissionall" }, @@ -35660,7 +35840,7 @@ "file_type": "code", "source_file": "tests/test_roles_coverage.py", "source_location": "L84", - "community": 491, + "community": 45, "norm_label": ".test_all_includes_all_permissions()", "id": "tests_test_roles_coverage_testpermissionall_test_all_includes_all_permissions" }, @@ -36101,7 +36281,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L6", - "community": 604, + "community": 576, "norm_label": "testsandboxtooldefinitions", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions" }, @@ -36110,7 +36290,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L7", - "community": 604, + "community": 576, "norm_label": ".test_execute_code_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_execute_code_in_registry" }, @@ -36119,7 +36299,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L10", - "community": 604, + "community": 576, "norm_label": ".test_read_file_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_read_file_in_registry" }, @@ -36128,7 +36308,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L13", - "community": 604, + "community": 576, "norm_label": ".test_write_file_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_write_file_in_registry" }, @@ -36137,7 +36317,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L16", - "community": 604, + "community": 576, "norm_label": ".test_list_files_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_list_files_in_registry" }, @@ -36146,7 +36326,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L19", - "community": 604, + "community": 576, "norm_label": ".test_execute_code_has_docstring()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_execute_code_has_docstring" }, @@ -37307,7 +37487,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L451", - "community": 105, + "community": 136, "norm_label": ".test_deserialize_mixed_string_none_parses_json()", "id": "tests_test_stocks_api_coverage_testdeserializejsoncolumns_test_deserialize_mixed_string_none_parses_json" }, @@ -37325,7 +37505,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L498", - "community": 105, + "community": 136, "norm_label": "testfilterbysearchterms", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms" }, @@ -37334,7 +37514,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L501", - "community": 105, + "community": 136, "norm_label": "._make_manager()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_make_manager" }, @@ -37343,7 +37523,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L509", - "community": 105, + "community": 136, "norm_label": ".test_filter_empty_search_returns_all()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_empty_search_returns_all" }, @@ -37352,7 +37532,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L515", - "community": 105, + "community": 136, "norm_label": ".test_filter_ticker_index_hit()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_ticker_index_hit" }, @@ -37361,7 +37541,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L523", - "community": 105, + "community": 136, "norm_label": ".test_filter_multiple_terms_index()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_multiple_terms_index" }, @@ -37370,7 +37550,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L530", - "community": 105, + "community": 136, "norm_label": ".test_filter_no_index_match_fallback_to_str()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_no_index_match_fallback_to_str" }, @@ -37379,7 +37559,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L538", - "community": 105, + "community": 136, "norm_label": ".test_filter_fallback_multiple_terms()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_fallback_multiple_terms" }, @@ -37388,7 +37568,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L545", - "community": 105, + "community": 136, "norm_label": ".test_filter_case_insensitive()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_case_insensitive" }, @@ -38036,7 +38216,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1265", - "community": 529, + "community": 588, "norm_label": ".test_http_route_search_required()", "id": "tests_test_stocks_api_coverage_testquerylivecotation_test_http_route_search_required" }, @@ -38072,7 +38252,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1315", - "community": 562, + "community": 606, "norm_label": ".test_cotations_search_required()", "id": "tests_test_stocks_api_coverage_testquerylivecotation_test_cotations_search_required" }, @@ -38261,7 +38441,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L452", - "community": 105, + "community": 136, "norm_label": "regression: is_string_dtype fails when column has strings + none (pandas 2.x).", "id": "tests_test_stocks_api_coverage_rationale_452" }, @@ -38279,7 +38459,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L499", - "community": 105, + "community": 136, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_499" }, @@ -38531,7 +38711,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1266", - "community": 529, + "community": 588, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1266" }, @@ -38540,7 +38720,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1316", - "community": 562, + "community": 606, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1316" }, @@ -39782,7 +39962,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L1", - "community": 518, + "community": 584, "norm_label": "test_type_aware_decay.py", "id": "tests_test_type_aware_decay_py" }, @@ -39791,7 +39971,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L11", - "community": 518, + "community": 584, "norm_label": "_create()", "id": "tests_test_type_aware_decay_create" }, @@ -39800,7 +39980,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L29", - "community": 518, + "community": 584, "norm_label": "testtypeawaredecay", "id": "tests_test_type_aware_decay_testtypeawaredecay" }, @@ -39809,7 +39989,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L30", - "community": 518, + "community": 584, "norm_label": ".test_preference_decays_slowly()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_preference_decays_slowly" }, @@ -39818,7 +39998,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L36", - "community": 518, + "community": 584, "norm_label": ".test_context_decays_fast()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_context_decays_fast" }, @@ -39827,7 +40007,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L42", - "community": 518, + "community": 584, "norm_label": ".test_analysis_decays_normally()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_analysis_decays_normally" }, @@ -39836,7 +40016,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L48", - "community": 518, + "community": 584, "norm_label": ".test_feedback_decays_medium()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_feedback_decays_medium" }, @@ -39845,7 +40025,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L54", - "community": 518, + "community": 584, "norm_label": ".test_unknown_type_uses_default()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_unknown_type_uses_default" }, @@ -39854,7 +40034,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L60", - "community": 518, + "community": 584, "norm_label": ".test_mixed_types_all_correct()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_mixed_types_all_correct" }, @@ -39863,7 +40043,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L76", - "community": 518, + "community": 584, "norm_label": ".test_preference_survives_longer()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_preference_survives_longer" }, @@ -39872,7 +40052,7 @@ "file_type": "rationale", "source_file": "tests/test_type_aware_decay.py", "source_location": "L77", - "community": 518, + "community": 584, "norm_label": "after 10 cycles, preference (0.99^10) > context (0.90^10).", "id": "tests_test_type_aware_decay_rationale_77" }, @@ -39881,7 +40061,7 @@ "file_type": "code", "source_file": "tests/test_user_deps.py", "source_location": "L1", - "community": 482, + "community": 519, "norm_label": "test_user_deps.py", "id": "tests_test_user_deps_py" }, @@ -40016,7 +40196,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L1", - "community": 104, + "community": 131, "norm_label": "test_vector_utils.py", "id": "tests_test_vector_utils_py" }, @@ -40025,7 +40205,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L6", - "community": 104, + "community": 72, "norm_label": "testbatchcosinesimilarity", "id": "tests_test_vector_utils_testbatchcosinesimilarity" }, @@ -40034,7 +40214,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L7", - "community": 104, + "community": 72, "norm_label": ".test_empty_matrix()", "id": "tests_test_vector_utils_testbatchcosinesimilarity_test_empty_matrix" }, @@ -40043,7 +40223,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L11", - "community": 104, + "community": 72, "norm_label": ".test_single_row()", "id": "tests_test_vector_utils_testbatchcosinesimilarity_test_single_row" }, @@ -40052,7 +40232,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L17", - "community": 104, + "community": 72, "norm_label": ".test_multiple_rows()", "id": "tests_test_vector_utils_testbatchcosinesimilarity_test_multiple_rows" }, @@ -40061,7 +40241,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L32", - "community": 104, + "community": 72, "norm_label": ".test_zero_query()", "id": "tests_test_vector_utils_testbatchcosinesimilarity_test_zero_query" }, @@ -41447,7 +41627,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1120", - "community": 148, + "community": 99, "norm_label": "generic exception in chat propagates to fastapi's default 500 handler.", "id": "tests_test_controllers_coverage_rationale_1120" }, @@ -41456,7 +41636,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1138", - "community": 511, + "community": 605, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1138" }, @@ -41501,7 +41681,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1196", - "community": 609, + "community": 14, "norm_label": "covers lines 57-60: admin bypasses permission check and generates key.", "id": "tests_test_controllers_coverage_rationale_1196" }, @@ -41510,7 +41690,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1208", - "community": 609, + "community": 14, "norm_label": "covers lines 61-63: exception during key generation (admin path).", "id": "tests_test_controllers_coverage_rationale_1208" }, @@ -41537,7 +41717,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1243", - "community": 588, + "community": 493, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1243" }, @@ -41564,7 +41744,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1301", - "community": 592, + "community": 493, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1301" }, @@ -41582,7 +41762,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1334", - "community": 544, + "community": 493, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1334" }, @@ -41591,7 +41771,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1351", - "community": 560, + "community": 493, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1351" }, @@ -41798,7 +41978,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L30", - "community": 474, + "community": 140, "norm_label": "keys with jaccard > 0.8 should merge.", "id": "tests_test_memory_dedup_rationale_30" }, @@ -41807,7 +41987,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L40", - "community": 474, + "community": 140, "norm_label": "keys with low similarity should not merge.", "id": "tests_test_memory_dedup_rationale_40" }, @@ -41816,7 +41996,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L67", - "community": 474, + "community": 140, "norm_label": "keys with jaccard <= 0.8 should not merge.", "id": "tests_test_memory_dedup_rationale_67" }, @@ -44669,7 +44849,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L1", - "community": 535, + "community": 105, "norm_label": "cache.py", "id": "main_app_prometheus_cache_py" }, @@ -44678,7 +44858,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L7", - "community": 535, + "community": 105, "norm_label": "resultcache", "id": "prometheus_cache_resultcache" }, @@ -44687,7 +44867,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L8", - "community": 535, + "community": 105, "norm_label": ".__init__()", "id": "prometheus_cache_resultcache_init" }, @@ -44696,7 +44876,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L11", - "community": 535, + "community": 105, "norm_label": ".cachepath()", "id": "prometheus_cache_resultcache_cachepath" }, @@ -44705,7 +44885,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L15", - "community": 535, + "community": 105, "norm_label": ".get()", "id": "prometheus_cache_resultcache_get" }, @@ -44714,7 +44894,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L21", - "community": 535, + "community": 105, "norm_label": ".set()", "id": "prometheus_cache_resultcache_set" }, @@ -44723,7 +44903,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L31", - "community": 535, + "community": 105, "norm_label": ".invalidate()", "id": "prometheus_cache_resultcache_invalidate" }, @@ -44732,7 +44912,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L38", - "community": 535, + "community": 105, "norm_label": ".exists()", "id": "prometheus_cache_resultcache_exists" }, @@ -45065,7 +45245,7 @@ "file_type": "code", "source_file": "tests/test_config_sandbox.py", "source_location": "L1", - "community": 102, + "community": 586, "norm_label": "test_config_sandbox.py", "id": "tests_test_config_sandbox_py" }, @@ -45074,7 +45254,7 @@ "file_type": "code", "source_file": "tests/test_config_sandbox.py", "source_location": "L5", - "community": 102, + "community": 586, "norm_label": "testsandboxconfig", "id": "tests_test_config_sandbox_testsandboxconfig" }, @@ -45083,7 +45263,7 @@ "file_type": "code", "source_file": "tests/test_config_sandbox.py", "source_location": "L6", - "community": 102, + "community": 586, "norm_label": ".test_sandbox_defaults()", "id": "tests_test_config_sandbox_testsandboxconfig_test_sandbox_defaults" }, @@ -45092,7 +45272,7 @@ "file_type": "code", "source_file": "tests/test_config_sandbox.py", "source_location": "L13", - "community": 102, + "community": 586, "norm_label": ".test_sandbox_fields_exist()", "id": "tests_test_config_sandbox_testsandboxconfig_test_sandbox_fields_exist" }, @@ -45101,7 +45281,7 @@ "file_type": "code", "source_file": "tests/test_config_sandbox.py", "source_location": "L21", - "community": 102, + "community": 586, "norm_label": ".test_sandbox_types()", "id": "tests_test_config_sandbox_testsandboxconfig_test_sandbox_types" }, @@ -45362,7 +45542,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L12", - "community": 604, + "community": 576, "norm_label": ".test_read_sandbox_file_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_read_sandbox_file_in_registry" }, @@ -45371,7 +45551,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L15", - "community": 604, + "community": 576, "norm_label": ".test_check_cache_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_check_cache_in_registry" }, @@ -45380,7 +45560,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L23", - "community": 604, + "community": 576, "norm_label": ".test_read_sandbox_file_has_docstring()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_read_sandbox_file_has_docstring" }, @@ -45389,7 +45569,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L28", - "community": 604, + "community": 576, "norm_label": ".test_check_cache_has_docstring()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_check_cache_has_docstring" }, @@ -45722,7 +45902,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L19", - "community": 535, + "community": 105, "norm_label": "._cache_path()", "id": "prometheus_cache_resultcache_cache_path" }, @@ -45731,7 +45911,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L1", - "community": 535, + "community": 105, "norm_label": "resultcache \u2014 sha256-keyed file-based cache for computed results.", "id": "prometheus_cache_rationale_1" }, @@ -45740,7 +45920,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L10", - "community": 535, + "community": 105, "norm_label": "file-based cache keyed by sha256 of code. stores results as json under:", "id": "prometheus_cache_rationale_10" }, @@ -45749,7 +45929,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L24", - "community": 535, + "community": 105, "norm_label": "return cached result dict or none if miss.", "id": "prometheus_cache_rationale_24" }, @@ -45758,7 +45938,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L31", - "community": 535, + "community": 105, "norm_label": "store result with timestamp.", "id": "prometheus_cache_rationale_31" }, @@ -45767,7 +45947,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L42", - "community": 535, + "community": 105, "norm_label": "delete all cached results for a session.", "id": "prometheus_cache_rationale_42" }, @@ -45776,7 +45956,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L50", - "community": 535, + "community": 105, "norm_label": "check if a result exists for the given code.", "id": "prometheus_cache_rationale_50" }, @@ -46379,7 +46559,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L46", - "community": 116, + "community": 602, "norm_label": "executememorytool()", "id": "prometheus_tools_executememorytool" }, @@ -46397,7 +46577,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L52", - "community": 474, + "community": 140, "norm_label": "keys with low similarity should not merge.", "id": "tests_test_memory_dedup_rationale_52" }, @@ -46406,7 +46586,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L85", - "community": 474, + "community": 140, "norm_label": "keys with jaccard <= 0.8 should not merge.", "id": "tests_test_memory_dedup_rationale_85" }, @@ -46532,7 +46712,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L89", - "community": 589, + "community": 529, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_89" }, @@ -46568,7 +46748,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L92", - "community": 589, + "community": 529, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_92" }, @@ -46613,7 +46793,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L85", - "community": 518, + "community": 614, "norm_label": "score below threshold + accesscount=0 + 90+ days \u2192 archived.", "id": "tests_test_memory_maintenance_rationale_85" }, @@ -46622,7 +46802,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L92", - "community": 518, + "community": 617, "norm_label": "low score but accessed recently \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_92" }, @@ -46640,7 +46820,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L106", - "community": 518, + "community": 613, "norm_label": "even with low score, if accessed \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_106" }, @@ -46658,7 +46838,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L134", - "community": 518, + "community": 592, "norm_label": "decay happens first, then archive check with new scores.", "id": "tests_test_memory_maintenance_rationale_134" }, @@ -46667,7 +46847,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L143", - "community": 518, + "community": 592, "norm_label": "score that decays to >= threshold stays alive. 0.11 * 0.95 = 0.1045 >= 0.1.", "id": "tests_test_memory_maintenance_rationale_143" }, @@ -46676,7 +46856,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L156", - "community": 518, + "community": 592, "norm_label": "89 days with low score \u2192 not archived (need > 90).", "id": "tests_test_memory_maintenance_rationale_156" }, @@ -46685,7 +46865,7 @@ "file_type": "code", "source_file": "main/utils/models/loader.py", "source_location": "L23", - "community": 116, + "community": 602, "norm_label": "embed()", "id": "models_loader_embed" }, @@ -46865,7 +47045,7 @@ "file_type": "code", "source_file": "main/utils/models/loader.py", "source_location": "L11", - "community": 605, + "community": 602, "norm_label": "_downloadmodel()", "id": "models_loader_downloadmodel" }, @@ -47000,7 +47180,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1277", - "community": 578, + "community": 493, "norm_label": "covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval.", "id": "tests_test_controllers_coverage_rationale_1277" }, @@ -47009,7 +47189,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1302", - "community": 592, + "community": 493, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1302" }, @@ -47027,7 +47207,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1335", - "community": 544, + "community": 493, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1335" }, @@ -47036,7 +47216,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1352", - "community": 560, + "community": 493, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1352" }, @@ -47063,7 +47243,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1389", - "community": 544, + "community": 493, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1389" }, @@ -47333,7 +47513,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L91", - "community": 589, + "community": 529, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_91" }, @@ -47342,7 +47522,7 @@ "file_type": "code", "source_file": "main/utils/vector.py", "source_location": "L1", - "community": 184, + "community": 72, "norm_label": "vector.py", "id": "main_utils_vector_py" }, @@ -47351,7 +47531,7 @@ "file_type": "code", "source_file": "main/utils/vector.py", "source_location": "L8", - "community": 104, + "community": 72, "norm_label": "batchcosinesimilarity()", "id": "utils_vector_batchcosinesimilarity" }, @@ -47666,7 +47846,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L76", - "community": 589, + "community": 529, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_76" }, @@ -47720,7 +47900,7 @@ "file_type": "code", "source_file": "main/app/prometheus/agent.py", "source_location": "L91", - "community": 116, + "community": 602, "norm_label": "executememorytool()", "id": "prometheus_agent_executememorytool" }, @@ -47756,7 +47936,7 @@ "file_type": "code", "source_file": "main/controller/prometheus_controller.py", "source_location": "L177", - "community": 116, + "community": 602, "norm_label": "creatememory()", "id": "controller_prometheus_controller_creatememory" }, @@ -47774,7 +47954,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L1", - "community": 67, + "community": 474, "norm_label": "test_memory_controller.py", "id": "tests_test_memory_controller_py" }, @@ -47837,7 +48017,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L65", - "community": 67, + "community": 474, "norm_label": "testmemoryendpointsintegration", "id": "tests_test_memory_controller_testmemoryendpointsintegration" }, @@ -47846,7 +48026,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L67", - "community": 67, + "community": 474, "norm_label": "test_get_memories_calls_manager()", "id": "tests_test_memory_controller_test_get_memories_calls_manager" }, @@ -47855,7 +48035,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L90", - "community": 67, + "community": 474, "norm_label": "test_create_memory_calls_manager()", "id": "tests_test_memory_controller_test_create_memory_calls_manager" }, @@ -47864,7 +48044,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L111", - "community": 67, + "community": 474, "norm_label": "test_create_memory_limit_reached()", "id": "tests_test_memory_controller_test_create_memory_limit_reached" }, @@ -47873,7 +48053,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L126", - "community": 67, + "community": 474, "norm_label": "test_delete_memory_calls_manager()", "id": "tests_test_memory_controller_test_delete_memory_calls_manager" }, @@ -47882,7 +48062,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L135", - "community": 67, + "community": 474, "norm_label": "test_delete_memory_not_found()", "id": "tests_test_memory_controller_test_delete_memory_not_found" }, @@ -47891,7 +48071,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L141", - "community": 67, + "community": 474, "norm_label": ".test_create_memory_missing_key()", "id": "tests_test_memory_controller_testmemoryendpointsintegration_test_create_memory_missing_key" }, @@ -47900,7 +48080,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L145", - "community": 67, + "community": 474, "norm_label": ".test_create_memory_missing_value()", "id": "tests_test_memory_controller_testmemoryendpointsintegration_test_create_memory_missing_value" }, @@ -47918,7 +48098,7 @@ "file_type": "rationale", "source_file": "main/utils/vector.py", "source_location": "L6", - "community": 184, + "community": 72, "norm_label": "vectorized cosine similarity: one query against n embeddings.", "id": "utils_vector_rationale_6" }, @@ -48440,7 +48620,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L138", - "community": 53, + "community": 104, "norm_label": "_fulltext_search()", "id": "prometheus_memory_fulltext_search" }, @@ -48566,7 +48746,7 @@ "file_type": "code", "source_file": "main/controller/prometheus_controller.py", "source_location": "L177", - "community": 116, + "community": 602, "norm_label": "create_memory()", "id": "controller_prometheus_controller_create_memory" }, @@ -48584,7 +48764,7 @@ "file_type": "code", "source_file": "main/utils/vector.py", "source_location": "L5", - "community": 184, + "community": 72, "norm_label": "pack_vector()", "id": "utils_vector_pack_vector" }, @@ -48593,7 +48773,7 @@ "file_type": "code", "source_file": "main/utils/vector.py", "source_location": "L11", - "community": 184, + "community": 72, "norm_label": "unpack_vector()", "id": "utils_vector_unpack_vector" }, @@ -48611,7 +48791,7 @@ "file_type": "code", "source_file": "main/utils/vector.py", "source_location": "L28", - "community": 104, + "community": 72, "norm_label": "batch_cosine_similarity()", "id": "utils_vector_batch_cosine_similarity" }, @@ -48629,7 +48809,7 @@ "file_type": "rationale", "source_file": "main/utils/vector.py", "source_location": "L12", - "community": 184, + "community": 72, "norm_label": "unpack mysql blob to float list.", "id": "utils_vector_rationale_12" }, @@ -48647,7 +48827,7 @@ "file_type": "rationale", "source_file": "main/utils/vector.py", "source_location": "L29", - "community": 104, + "community": 72, "norm_label": "vectorized cosine similarity: one query against n embeddings.", "id": "utils_vector_rationale_29" }, @@ -48719,7 +48899,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L75", - "community": 67, + "community": 474, "norm_label": "full integration tests using mocked memorymanager.", "id": "tests_test_memory_controller_rationale_75" }, @@ -48773,7 +48953,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L141", - "community": 67, + "community": 474, "norm_label": "post /memories rejects missing key.", "id": "tests_test_memory_controller_rationale_141" }, @@ -48782,7 +48962,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L146", - "community": 67, + "community": 474, "norm_label": "post /memories rejects missing value.", "id": "tests_test_memory_controller_rationale_146" }, @@ -48953,7 +49133,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L11", - "community": 184, + "community": 72, "norm_label": "testpackunpack", "id": "tests_test_vector_utils_testpackunpack" }, @@ -48962,7 +49142,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L12", - "community": 184, + "community": 72, "norm_label": ".test_roundtrip()", "id": "tests_test_vector_utils_testpackunpack_test_roundtrip" }, @@ -48971,7 +49151,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L20", - "community": 184, + "community": 72, "norm_label": ".test_empty()", "id": "tests_test_vector_utils_testpackunpack_test_empty" }, @@ -48980,7 +49160,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L26", - "community": 184, + "community": 72, "norm_label": ".test_384_dims()", "id": "tests_test_vector_utils_testpackunpack_test_384_dims" }, @@ -49043,7 +49223,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L13", - "community": 184, + "community": 72, "norm_label": "pack \u2192 unpack preserves values.", "id": "tests_test_vector_utils_rationale_13" }, @@ -49052,7 +49232,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L21", - "community": 184, + "community": 72, "norm_label": "empty list roundtrips.", "id": "tests_test_vector_utils_rationale_21" }, @@ -49061,7 +49241,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L27", - "community": 184, + "community": 72, "norm_label": "384-dim vector packs to 1536 bytes.", "id": "tests_test_vector_utils_rationale_27" }, @@ -49115,7 +49295,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L68", - "community": 104, + "community": 72, "norm_label": "empty matrix \u2192 empty array.", "id": "tests_test_vector_utils_rationale_68" }, @@ -49124,7 +49304,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L73", - "community": 104, + "community": 72, "norm_label": "single row matches cosine_similarity.", "id": "tests_test_vector_utils_rationale_73" }, @@ -49133,7 +49313,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L80", - "community": 104, + "community": 72, "norm_label": "multiple rows ranked correctly.", "id": "tests_test_vector_utils_rationale_80" }, @@ -49142,7 +49322,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L93", - "community": 104, + "community": 72, "norm_label": "zero query \u2192 all zeros.", "id": "tests_test_vector_utils_rationale_93" }, @@ -50159,7 +50339,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L74", - "community": 251, + "community": 535, "norm_label": "testclient with stocks router + verifyapikey + getcurrentuser overrides.", "id": "tests_conftest_rationale_74" }, @@ -50168,7 +50348,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L99", - "community": 251, + "community": 535, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_99" }, @@ -50267,7 +50447,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L724", - "community": 136, + "community": 120, "norm_label": "covers lines 126-136: delete /user/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_724" }, @@ -50276,7 +50456,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L727", - "community": 136, + "community": 120, "norm_label": "covers lines 126, 131, 135-136.", "id": "tests_test_controllers_coverage_rationale_727" }, @@ -50285,7 +50465,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L754", - "community": 136, + "community": 120, "norm_label": "covers lines 127-129: session not found.", "id": "tests_test_controllers_coverage_rationale_754" }, @@ -50294,7 +50474,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L776", - "community": 136, + "community": 120, "norm_label": "covers lines 132-133: revokesession returns false.", "id": "tests_test_controllers_coverage_rationale_776" }, @@ -50321,7 +50501,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L832", - "community": 610, + "community": 45, "norm_label": "covers line 24: get /prometheus/health.", "id": "tests_test_controllers_coverage_rationale_832" }, @@ -50330,7 +50510,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L846", - "community": 45, + "community": 99, "norm_label": "covers lines 33-36: get /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_846" }, @@ -50339,7 +50519,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L864", - "community": 45, + "community": 99, "norm_label": "covers line 52: post /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_864" }, @@ -50411,7 +50591,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L994", - "community": 584, + "community": 99, "norm_label": "covers lines 95-98: delete /prometheus/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_994" }, @@ -50420,7 +50600,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L997", - "community": 584, + "community": 99, "norm_label": "covers lines 95-98: session deleted.", "id": "tests_test_controllers_coverage_rationale_997" }, @@ -50429,7 +50609,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1007", - "community": 584, + "community": 99, "norm_label": "covers lines 96-97: session not found.", "id": "tests_test_controllers_coverage_rationale_1007" }, @@ -50474,7 +50654,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1116", - "community": 148, + "community": 99, "norm_label": "generic exception in chat propagates to fastapi's default 500 handler.", "id": "tests_test_controllers_coverage_rationale_1116" }, @@ -50483,7 +50663,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1134", - "community": 511, + "community": 605, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1134" }, @@ -50528,7 +50708,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1192", - "community": 609, + "community": 14, "norm_label": "covers lines 57-60: admin bypasses permission check and generates key.", "id": "tests_test_controllers_coverage_rationale_1192" }, @@ -50537,7 +50717,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1204", - "community": 609, + "community": 14, "norm_label": "covers lines 61-63: exception during key generation (admin path).", "id": "tests_test_controllers_coverage_rationale_1204" }, @@ -50564,7 +50744,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1239", - "community": 588, + "community": 493, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1239" }, @@ -50591,7 +50771,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1273", - "community": 578, + "community": 493, "norm_label": "covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval.", "id": "tests_test_controllers_coverage_rationale_1273" }, @@ -50600,7 +50780,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1298", - "community": 592, + "community": 493, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1298" }, @@ -50618,7 +50798,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1331", - "community": 544, + "community": 493, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1331" }, @@ -50627,7 +50807,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1348", - "community": 560, + "community": 493, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1348" }, @@ -50879,7 +51059,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L722", - "community": 136, + "community": 120, "norm_label": "covers lines 126-136: delete /user/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_722" }, @@ -50888,7 +51068,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L725", - "community": 136, + "community": 120, "norm_label": "covers lines 126, 131, 135-136.", "id": "tests_test_controllers_coverage_rationale_725" }, @@ -50897,7 +51077,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L752", - "community": 136, + "community": 120, "norm_label": "covers lines 127-129: session not found.", "id": "tests_test_controllers_coverage_rationale_752" }, @@ -50906,7 +51086,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L774", - "community": 136, + "community": 120, "norm_label": "covers lines 132-133: revokesession returns false.", "id": "tests_test_controllers_coverage_rationale_774" }, @@ -50933,7 +51113,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L830", - "community": 610, + "community": 45, "norm_label": "covers line 24: get /prometheus/health.", "id": "tests_test_controllers_coverage_rationale_830" }, @@ -50942,7 +51122,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L844", - "community": 45, + "community": 99, "norm_label": "covers lines 33-36: get /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_844" }, @@ -50951,7 +51131,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L862", - "community": 45, + "community": 99, "norm_label": "covers line 52: post /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_862" }, @@ -51023,7 +51203,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L992", - "community": 584, + "community": 99, "norm_label": "covers lines 95-98: delete /prometheus/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_992" }, @@ -51032,7 +51212,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L995", - "community": 584, + "community": 99, "norm_label": "covers lines 95-98: session deleted.", "id": "tests_test_controllers_coverage_rationale_995" }, @@ -51041,7 +51221,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1005", - "community": 584, + "community": 99, "norm_label": "covers lines 96-97: session not found.", "id": "tests_test_controllers_coverage_rationale_1005" }, @@ -51086,7 +51266,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1115", - "community": 148, + "community": 99, "norm_label": "generic exception in chat propagates to fastapi's default 500 handler.", "id": "tests_test_controllers_coverage_rationale_1115" }, @@ -51095,7 +51275,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1133", - "community": 511, + "community": 605, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1133" }, @@ -51140,7 +51320,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1191", - "community": 609, + "community": 14, "norm_label": "covers lines 57-60: admin bypasses permission check and generates key.", "id": "tests_test_controllers_coverage_rationale_1191" }, @@ -51167,7 +51347,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1238", - "community": 588, + "community": 493, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1238" }, @@ -51194,7 +51374,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1272", - "community": 578, + "community": 493, "norm_label": "covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval.", "id": "tests_test_controllers_coverage_rationale_1272" }, @@ -51203,7 +51383,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1297", - "community": 588, + "community": 493, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1297" }, @@ -51221,7 +51401,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1330", - "community": 544, + "community": 493, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1330" }, @@ -51230,7 +51410,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1347", - "community": 560, + "community": 493, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1347" }, @@ -51761,7 +51941,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L528", - "community": 105, + "community": 136, "norm_label": "regression: is_string_dtype fails when column has strings + none (pandas 2.x).", "id": "tests_test_stocks_api_coverage_rationale_528" }, @@ -51779,7 +51959,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L575", - "community": 105, + "community": 136, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_575" }, @@ -52022,7 +52202,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1342", - "community": 529, + "community": 588, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1342" }, @@ -52031,7 +52211,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1392", - "community": 562, + "community": 606, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1392" }, @@ -52157,7 +52337,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1344", - "community": 529, + "community": 588, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1344" }, @@ -52166,7 +52346,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1394", - "community": 562, + "community": 606, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1394" }, @@ -52346,7 +52526,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1400", - "community": 529, + "community": 588, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1400" }, @@ -52355,7 +52535,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1468", - "community": 562, + "community": 606, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1468" }, @@ -52526,7 +52706,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L527", - "community": 105, + "community": 136, "norm_label": "regression: is_string_dtype fails when column has strings + none (pandas 2.x).", "id": "tests_test_stocks_api_coverage_rationale_527" }, @@ -52544,7 +52724,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L574", - "community": 105, + "community": 136, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_574" }, @@ -52778,7 +52958,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1396", - "community": 529, + "community": 588, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1396" }, @@ -52787,7 +52967,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1464", - "community": 562, + "community": 606, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1464" }, @@ -52814,7 +52994,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1388", - "community": 529, + "community": 588, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1388" }, @@ -52823,7 +53003,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1456", - "community": 562, + "community": 606, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1456" }, @@ -53687,7 +53867,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L63", - "community": 222, + "community": 81, "norm_label": "getrealtimecotation()", "id": "controller_stocksapi_controller_getrealtimecotation" }, @@ -53795,7 +53975,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L23", - "community": 222, + "community": 81, "norm_label": "apikeytest()", "id": "controller_stocksapi_controller_apikeytest" }, @@ -53849,7 +54029,7 @@ "file_type": "code", "source_file": "main/utils/http_session.py", "source_location": "L18", - "community": 612, + "community": 578, "norm_label": "cleanup()", "id": "utils_http_session_cleanup" }, @@ -53894,7 +54074,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L75", - "community": 251, + "community": 535, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_75" }, @@ -53903,7 +54083,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L20", - "community": 504, + "community": 604, "norm_label": "dbsession()", "id": "tests_test_api_key_quota_atomic_dbsession" }, @@ -53912,7 +54092,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L21", - "community": 504, + "community": 604, "norm_label": "create an in-memory sqlite database for testing.", "id": "tests_test_api_key_quota_atomic_rationale_21" }, @@ -53921,7 +54101,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L34", - "community": 504, + "community": 604, "norm_label": "sample api key data for tests.", "id": "tests_test_api_key_quota_atomic_rationale_34" }, @@ -53975,7 +54155,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L166", - "community": 572, + "community": 608, "norm_label": "test that invalid api key returns zero rows affected.", "id": "tests_test_api_key_quota_atomic_rationale_166" }, @@ -53984,7 +54164,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L180", - "community": 572, + "community": 608, "norm_label": "test that multiple api keys have independent quotas.", "id": "tests_test_api_key_quota_atomic_rationale_180" }, @@ -54074,7 +54254,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1194", - "community": 14, + "community": 45, "norm_label": "teststocksapikeytest", "id": "tests_test_controllers_coverage_teststocksapikeytest" }, @@ -54110,7 +54290,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L132", - "community": 491, + "community": 45, "norm_label": "covers line 28: get /auth/health.", "id": "tests_test_controllers_coverage_rationale_132" }, @@ -54119,7 +54299,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L148", - "community": 120, + "community": 45, "norm_label": "covers lines 44-54, 63, 66-71: register success, valueerror, generic exception.", "id": "tests_test_controllers_coverage_rationale_148" }, @@ -54146,7 +54326,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L228", - "community": 120, + "community": 45, "norm_label": "covers lines 87-93, 102: login success and failure paths.", "id": "tests_test_controllers_coverage_rationale_228" }, @@ -54227,7 +54407,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L379", - "community": 491, + "community": 45, "norm_label": "covers lines 139, 141-149: googlelogin endpoint.", "id": "tests_test_controllers_coverage_rationale_379" }, @@ -54254,7 +54434,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L425", - "community": 120, + "community": 45, "norm_label": "covers lines 155-156, 158, 160-168, 170-177, 179-184, 186, 190-204: googlecallba", "id": "tests_test_controllers_coverage_rationale_425" }, @@ -54371,7 +54551,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L767", - "community": 136, + "community": 120, "norm_label": "covers lines 126-136: delete /user/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_767" }, @@ -54380,7 +54560,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L770", - "community": 136, + "community": 120, "norm_label": "covers lines 126, 131, 135-136.", "id": "tests_test_controllers_coverage_rationale_770" }, @@ -54389,7 +54569,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L797", - "community": 136, + "community": 120, "norm_label": "covers lines 127-129: session not found.", "id": "tests_test_controllers_coverage_rationale_797" }, @@ -54398,7 +54578,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L819", - "community": 136, + "community": 120, "norm_label": "covers lines 132-133: revokesession returns false.", "id": "tests_test_controllers_coverage_rationale_819" }, @@ -54425,7 +54605,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L875", - "community": 610, + "community": 45, "norm_label": "covers line 24: get /prometheus/health.", "id": "tests_test_controllers_coverage_rationale_875" }, @@ -54434,7 +54614,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L889", - "community": 45, + "community": 99, "norm_label": "covers lines 33-36: get /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_889" }, @@ -54443,7 +54623,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L907", - "community": 45, + "community": 99, "norm_label": "covers line 52: post /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_907" }, @@ -54515,7 +54695,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1037", - "community": 584, + "community": 99, "norm_label": "covers lines 95-98: delete /prometheus/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_1037" }, @@ -54524,7 +54704,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1040", - "community": 584, + "community": 99, "norm_label": "covers lines 95-98: session deleted.", "id": "tests_test_controllers_coverage_rationale_1040" }, @@ -54533,7 +54713,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1050", - "community": 584, + "community": 99, "norm_label": "covers lines 96-97: session not found.", "id": "tests_test_controllers_coverage_rationale_1050" }, @@ -54578,7 +54758,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1160", - "community": 148, + "community": 99, "norm_label": "covers line 125, 126-128: generic exception in chat.", "id": "tests_test_controllers_coverage_rationale_1160" }, @@ -54587,7 +54767,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1181", - "community": 511, + "community": 605, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1181" }, @@ -54641,7 +54821,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1262", - "community": 609, + "community": 14, "norm_label": "covers lines 61-63: exception during key generation (admin path).", "id": "tests_test_controllers_coverage_rationale_1262" }, @@ -54668,7 +54848,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1356", - "community": 592, + "community": 493, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1356" }, @@ -54677,7 +54857,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1406", - "community": 560, + "community": 493, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1406" }, @@ -54758,7 +54938,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L28", - "community": 612, + "community": 578, "norm_label": "testcleanup", "id": "tests_test_http_session_coverage_testcleanup" }, @@ -54767,7 +54947,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L29", - "community": 612, + "community": 578, "norm_label": ".test_cleanup_closes_session()", "id": "tests_test_http_session_coverage_testcleanup_test_cleanup_closes_session" }, @@ -54776,7 +54956,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L37", - "community": 612, + "community": 578, "norm_label": ".test_cleanup_no_session()", "id": "tests_test_http_session_coverage_testcleanup_test_cleanup_no_session" }, @@ -54785,7 +54965,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L46", - "community": 612, + "community": 578, "norm_label": ".test_cleanup_exception_during_close()", "id": "tests_test_http_session_coverage_testcleanup_test_cleanup_exception_during_close" }, @@ -55343,7 +55523,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L526", - "community": 105, + "community": 136, "norm_label": "regression: is_string_dtype fails when column has strings + none (pandas 2.x).", "id": "tests_test_stocks_api_coverage_rationale_526" }, @@ -55361,7 +55541,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L573", - "community": 105, + "community": 136, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_573" }, @@ -56000,7 +56180,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L8", - "community": 618, + "community": 624, "norm_label": "checkmysqlconnection \u2014 success, errors, engine=none paths.", "id": "tests_test_connectivity_coverage_rationale_8" }, @@ -56009,7 +56189,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L105", - "community": 617, + "community": 623, "norm_label": "checkserviceconnection \u2014 success, not found, errors.", "id": "tests_test_connectivity_coverage_rationale_105" }, @@ -56180,7 +56360,7 @@ "file_type": "code", "source_file": "main/utils/errors.py", "source_location": "L27", - "community": 607, + "community": 572, "norm_label": "_build_error_response()", "id": "utils_errors_build_error_response" }, @@ -56189,7 +56369,7 @@ "file_type": "code", "source_file": "main/utils/errors.py", "source_location": "L37", - "community": 607, + "community": 572, "norm_label": "http_exception_handler()", "id": "utils_errors_http_exception_handler" }, @@ -56198,7 +56378,7 @@ "file_type": "code", "source_file": "main/utils/errors.py", "source_location": "L44", - "community": 607, + "community": 572, "norm_label": "validation_exception_handler()", "id": "utils_errors_validation_exception_handler" }, @@ -56207,7 +56387,7 @@ "file_type": "code", "source_file": "main/utils/errors.py", "source_location": "L56", - "community": 607, + "community": 572, "norm_label": "generic_exception_handler()", "id": "utils_errors_generic_exception_handler" }, @@ -56243,7 +56423,7 @@ "file_type": "rationale", "source_file": "main/utils/http_session.py", "source_location": "L23", - "community": 612, + "community": 578, "norm_label": "close the main thread's session at interpreter shutdown.", "id": "utils_http_session_rationale_23" }, @@ -56675,7 +56855,7 @@ "file_type": "code", "source_file": "main/service/user_service.py", "source_location": "L35", - "community": 72, + "community": 536, "norm_label": "inactivesessionsscheduler()", "id": "service_user_service_inactivesessionsscheduler" }, @@ -57143,7 +57323,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L522", - "community": 105, + "community": 136, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_522" }, @@ -57287,7 +57467,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L62", - "community": 251, + "community": 535, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_62" }, @@ -57296,7 +57476,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L61", - "community": 251, + "community": 535, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_61" }, @@ -57305,7 +57485,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L57", - "community": 251, + "community": 535, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_57" }, @@ -57314,7 +57494,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L49", - "community": 251, + "community": 535, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_49" }, @@ -57854,7 +58034,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L135", - "community": 502, + "community": 600, "norm_label": "testqueryoptimization", "id": "tests_test_stocks_cache_testqueryoptimization" }, @@ -57863,7 +58043,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L138", - "community": 502, + "community": 600, "norm_label": ".test_all_optimizations_present()", "id": "tests_test_stocks_cache_testqueryoptimization_test_all_optimizations_present" }, @@ -57872,7 +58052,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L153", - "community": 502, + "community": 600, "norm_label": ".test_query_filter_uses_optimization()", "id": "tests_test_stocks_cache_testqueryoptimization_test_query_filter_uses_optimization" }, @@ -58124,7 +58304,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L136", - "community": 502, + "community": 600, "norm_label": "integration tests for all query optimizations", "id": "tests_test_stocks_cache_rationale_136" }, @@ -58133,7 +58313,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L139", - "community": 502, + "community": 600, "norm_label": "all optimizations should be implemented", "id": "tests_test_stocks_cache_rationale_139" }, @@ -58142,7 +58322,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L154", - "community": 502, + "community": 600, "norm_label": "query filter should use ticker index", "id": "tests_test_stocks_cache_rationale_154" }, @@ -58412,7 +58592,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L138", - "community": 502, + "community": 600, "norm_label": "integration tests for all query optimizations", "id": "tests_test_stocks_cache_rationale_138" }, @@ -58421,7 +58601,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L141", - "community": 502, + "community": 600, "norm_label": "all optimizations should be implemented", "id": "tests_test_stocks_cache_rationale_141" }, @@ -58430,7 +58610,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L156", - "community": 502, + "community": 600, "norm_label": "query filter should use ticker index", "id": "tests_test_stocks_cache_rationale_156" }, @@ -58673,7 +58853,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L72", - "community": 498, + "community": 101, "norm_label": "testquerycaching", "id": "tests_test_stocks_optimization_testquerycaching" }, @@ -58682,7 +58862,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L75", - "community": 498, + "community": 101, "norm_label": ".test_cache_manager_has_caches_method()", "id": "tests_test_stocks_optimization_testquerycaching_test_cache_manager_has_caches_method" }, @@ -58691,7 +58871,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L83", - "community": 498, + "community": 101, "norm_label": ".test_querycache_ttl_configuration()", "id": "tests_test_stocks_optimization_testquerycaching_test_queryCache_ttl_configuration" }, @@ -58700,7 +58880,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L91", - "community": 498, + "community": 101, "norm_label": ".test_get_cached_stocks_respects_columns_parameter()", "id": "tests_test_stocks_optimization_testquerycaching_test_get_cached_stocks_respects_columns_parameter" }, @@ -58709,7 +58889,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L101", - "community": 498, + "community": 101, "norm_label": ".test_different_queries_not_cached()", "id": "tests_test_stocks_optimization_testquerycaching_test_different_queries_not_cached" }, @@ -58718,7 +58898,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L105", - "community": 498, + "community": 101, "norm_label": ".test_cache_expiry_after_ttl()", "id": "tests_test_stocks_optimization_testquerycaching_test_cache_expiry_after_ttl" }, @@ -58763,7 +58943,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L137", - "community": 101, + "community": 184, "norm_label": "testqueryoptimization", "id": "tests_test_stocks_optimization_testqueryoptimization" }, @@ -58772,7 +58952,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L140", - "community": 101, + "community": 184, "norm_label": ".test_all_optimizations_present()", "id": "tests_test_stocks_optimization_testqueryoptimization_test_all_optimizations_present" }, @@ -58781,7 +58961,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L155", - "community": 101, + "community": 184, "norm_label": ".test_query_filter_uses_optimization()", "id": "tests_test_stocks_optimization_testqueryoptimization_test_query_filter_uses_optimization" }, @@ -58853,7 +59033,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L301", - "community": 101, + "community": 498, "norm_label": "testfilterbysearchterms", "id": "tests_test_stocks_optimization_testfilterbysearchterms" }, @@ -58862,7 +59042,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L304", - "community": 101, + "community": 498, "norm_label": ".test_filter_with_tickerindex()", "id": "tests_test_stocks_optimization_testfilterbysearchterms_test_filter_with_tickerIndex" }, @@ -58943,7 +59123,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L73", - "community": 498, + "community": 101, "norm_label": "tests for query result caching", "id": "tests_test_stocks_optimization_rationale_73" }, @@ -58952,7 +59132,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L76", - "community": 498, + "community": 101, "norm_label": "cachemanager should track cached queries", "id": "tests_test_stocks_optimization_rationale_76" }, @@ -58961,7 +59141,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L84", - "community": 498, + "community": 101, "norm_label": "query cache should have configurable ttl", "id": "tests_test_stocks_optimization_rationale_84" }, @@ -58970,7 +59150,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L92", - "community": 498, + "community": 101, "norm_label": "getcachedstocks should support column filtering", "id": "tests_test_stocks_optimization_rationale_92" }, @@ -58979,7 +59159,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L102", - "community": 498, + "community": 101, "norm_label": "different query parameters should not share cache", "id": "tests_test_stocks_optimization_rationale_102" }, @@ -58988,7 +59168,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L106", - "community": 498, + "community": 101, "norm_label": "cache should expire after ttl", "id": "tests_test_stocks_optimization_rationale_106" }, @@ -59033,7 +59213,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L138", - "community": 101, + "community": 184, "norm_label": "integration tests for all query optimizations", "id": "tests_test_stocks_optimization_rationale_138" }, @@ -59042,7 +59222,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L141", - "community": 101, + "community": 184, "norm_label": "all optimizations should be implemented", "id": "tests_test_stocks_optimization_rationale_141" }, @@ -59051,7 +59231,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L156", - "community": 101, + "community": 184, "norm_label": "query filter should use ticker index", "id": "tests_test_stocks_optimization_rationale_156" }, @@ -59123,7 +59303,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L302", - "community": 101, + "community": 498, "norm_label": "tests for optimized search filtering", "id": "tests_test_stocks_optimization_rationale_302" }, @@ -59132,7 +59312,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L305", - "community": 101, + "community": 498, "norm_label": "filter should use ticker index for o(1) lookup", "id": "tests_test_stocks_optimization_rationale_305" }, @@ -59168,7 +59348,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L173", - "community": 101, + "community": 498, "norm_label": "tests for optimized search filtering", "id": "tests_test_stocks_optimization_rationale_173" }, @@ -59177,7 +59357,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L176", - "community": 101, + "community": 498, "norm_label": "filter should use ticker index for o(1) lookup", "id": "tests_test_stocks_optimization_rationale_176" }, @@ -59478,7 +59658,7 @@ "label": "FastAPI", "file_type": "rationale", "source_file": "README.md", - "community": 482, + "community": 519, "norm_label": "fastapi", "id": "fastapi" }, @@ -59518,7 +59698,7 @@ "label": "Authentication System", "file_type": "document", "source_file": "docs/authentication.md", - "community": 606, + "community": 560, "norm_label": "authentication system", "id": "authentication" }, @@ -59526,7 +59706,7 @@ "label": "JWT Authentication", "file_type": "rationale", "source_file": "docs/authentication.md", - "community": 606, + "community": 560, "norm_label": "jwt authentication", "id": "jwt" }, @@ -59534,7 +59714,7 @@ "label": "Google OAuth", "file_type": "rationale", "source_file": "docs/authentication.md", - "community": 606, + "community": 560, "norm_label": "google oauth", "id": "google_oauth" }, @@ -59622,7 +59802,7 @@ "label": "Pytest Testing", "file_type": "rationale", "source_file": "pyproject.toml", - "community": 93, + "community": 586, "norm_label": "pytest testing", "id": "pytest" }, @@ -68540,209 +68720,208 @@ { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L22", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L63", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_stocks_api_cache_py", - "target": "stocks_api_cache_optimizedtypes" + "source": "main_app_stocks_api_build_py", + "target": "stocks_api_build_buildfeathercache" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L58", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L155", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_stocks_api_cache_py", - "target": "stocks_api_cache_arrowtypefor" + "source": "main_app_stocks_api_build_py", + "target": "stocks_api_build_trybuildlock" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L50", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L173", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_stocks_api_cache_py", - "target": "stocks_api_cache_buildfeathercache" + "source": "main_app_stocks_api_build_py", + "target": "stocks_api_build_readfeatherdataframe" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L90", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L46", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_stocks_api_cache_py", - "target": "stocks_api_cache_trybuildlock" + "source": "main_app_stocks_api_build_py", + "target": "stocks_api_build_runtimeconf" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L170", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_stocks_api_cache_py", - "target": "stocks_api_cache_sortcacheframe" + "source": "stocks_api_build_rationale_1", + "target": "main_app_stocks_api_build_py" }, { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L190", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/stocks_api/build.py", + "source_location": "L104", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_stocks_api_cache_py", - "target": "stocks_api_cache_buildtickerindex" + "source": "stocks_api_build_buildfeathercache", + "target": "stocks_api_frame_optimizedtypes" }, { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L206", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/stocks_api/build.py", + "source_location": "L117", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_stocks_api_cache_py", - "target": "stocks_api_cache_readfeatherdataframe" + "source": "stocks_api_build_buildfeathercache", + "target": "stocks_api_frame_arrowtypefor" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L12", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L68", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_stocks_api_cache_py", - "target": "stocks_api_cache_stockscachemanager" + "source": "stocks_api_build_buildfeathercache", + "target": "stocks_api_build_runtimeconf" }, { - "relation": "contains", - "confidence": "EXTRACTED", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, "source_file": "main/app/stocks_api/cache.py", - "source_location": "L38", + "source_location": "L116", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_stocks_api_cache_py", - "target": "stocks_api_cache_buildcotationdateindex" + "source": "stocks_api_cache_stockscachemanager_getcachedstocks", + "target": "stocks_api_build_trybuildlock" }, { "relation": "calls", "context": "call", "confidence": "EXTRACTED", - "source_file": "main/app/stocks_api/cache.py", - "source_location": "L71", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L158", "weight": 1.0, "confidence_score": 1.0, - "source": "stocks_api_cache_buildfeathercache", - "target": "stocks_api_cache_optimizedtypes" + "source": "stocks_api_build_trybuildlock", + "target": "stocks_api_build_runtimeconf" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", + "confidence": "INFERRED", + "confidence_score": 0.8, "source_file": "main/app/stocks_api/cache.py", - "source_location": "L89", + "source_location": "L80", "weight": 1.0, - "confidence_score": 1.0, - "source": "stocks_api_cache_optimizedtypes", - "target": "stocks_api_cache_stockscachemanager_getcachedstocks" + "source": "stocks_api_cache_stockscachemanager_loadfromfeather", + "target": "stocks_api_build_readfeatherdataframe" }, { - "relation": "calls", - "context": "call", + "relation": "contains", "confidence": "EXTRACTED", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L124", + "source_location": "L12", "weight": 1.0, "confidence_score": 1.0, - "source": "stocks_api_cache_buildfeathercache", - "target": "stocks_api_cache_arrowtypefor" + "source": "main_app_stocks_api_cache_py", + "target": "stocks_api_cache_stockscachemanager" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L59", + "source_location": "L22", "weight": 1.0, "confidence_score": 1.0, - "source": "stocks_api_cache_rationale_59", - "target": "stocks_api_cache_arrowtypefor" + "source": "main_app_stocks_api_cache_py", + "target": "stocks_api_cache_optimizedtypes" }, { - "relation": "calls", - "context": "call", + "relation": "contains", "confidence": "EXTRACTED", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L157", + "source_location": "L58", "weight": 1.0, "confidence_score": 1.0, - "source": "stocks_api_cache_stockscachemanager_getcachedstocks", - "target": "stocks_api_cache_trybuildlock" + "source": "main_app_stocks_api_cache_py", + "target": "stocks_api_cache_arrowtypefor" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L91", + "source_location": "L50", "weight": 1.0, "confidence_score": 1.0, - "source": "stocks_api_cache_rationale_91", - "target": "stocks_api_cache_trybuildlock" + "source": "main_app_stocks_api_cache_py", + "target": "stocks_api_cache_buildfeathercache" }, { - "relation": "calls", - "context": "call", + "relation": "contains", "confidence": "EXTRACTED", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L239", + "source_location": "L90", "weight": 1.0, "confidence_score": 1.0, - "source": "stocks_api_cache_stockscachemanager_loadfromfeather", - "target": "stocks_api_cache_sortcacheframe" + "source": "main_app_stocks_api_cache_py", + "target": "stocks_api_cache_trybuildlock" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L171", + "source_location": "L170", "weight": 1.0, "confidence_score": 1.0, - "source": "stocks_api_cache_rationale_171", + "source": "main_app_stocks_api_cache_py", "target": "stocks_api_cache_sortcacheframe" }, { - "relation": "calls", - "context": "call", + "relation": "contains", "confidence": "EXTRACTED", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L240", + "source_location": "L190", "weight": 1.0, "confidence_score": 1.0, - "source": "stocks_api_cache_stockscachemanager_loadfromfeather", + "source": "main_app_stocks_api_cache_py", "target": "stocks_api_cache_buildtickerindex" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L191", + "source_location": "L206", "weight": 1.0, "confidence_score": 1.0, - "source": "stocks_api_cache_rationale_191", - "target": "stocks_api_cache_buildtickerindex" + "source": "main_app_stocks_api_cache_py", + "target": "stocks_api_cache_readfeatherdataframe" }, { - "relation": "calls", - "context": "call", + "relation": "contains", "confidence": "EXTRACTED", "source_file": "main/app/stocks_api/cache.py", - "source_location": "L238", + "source_location": "L38", "weight": 1.0, "confidence_score": 1.0, - "source": "stocks_api_cache_stockscachemanager_loadfromfeather", - "target": "stocks_api_cache_readfeatherdataframe" + "source": "main_app_stocks_api_cache_py", + "target": "stocks_api_cache_buildcotationdateindex" }, { "relation": "method", @@ -69609,6 +69788,61 @@ "source": "stocks_api_cache_stockscachemanager_getcachedstocks", "target": "stocks_api_cache_stockscachemanager_loadfromfeather" }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L84", + "weight": 1.0, + "source": "stocks_api_cache_stockscachemanager_loadfromfeather", + "target": "stocks_api_frame_sortcacheframe" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L85", + "weight": 1.0, + "source": "stocks_api_cache_stockscachemanager_loadfromfeather", + "target": "stocks_api_frame_buildtickerindex" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L239", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_cache_stockscachemanager_loadfromfeather", + "target": "stocks_api_cache_sortcacheframe" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L240", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_cache_stockscachemanager_loadfromfeather", + "target": "stocks_api_cache_buildtickerindex" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L238", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_cache_stockscachemanager_loadfromfeather", + "target": "stocks_api_cache_readfeatherdataframe" + }, { "relation": "calls", "context": "call", @@ -69631,6 +69865,28 @@ "source": "stocks_api_cache_stockscachemanager_loadfromfeather", "target": "stocks_api_sync_cache_clearendpointcache" }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L89", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_cache_optimizedtypes", + "target": "stocks_api_cache_stockscachemanager_getcachedstocks" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L157", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_cache_stockscachemanager_getcachedstocks", + "target": "stocks_api_cache_trybuildlock" + }, { "relation": "calls", "context": "call", @@ -69818,6 +70074,16 @@ "source": "stocks_api_compress_getabbr", "target": "stocks_api_util_generateabbreviations" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/compress.py", + "source_location": "L31", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_compress_rationale_31", + "target": "stocks_api_compress_getabbr" + }, { "relation": "calls", "context": "call", @@ -69851,6 +70117,16 @@ "source": "controller_stocksapi_controller_listfields", "target": "stocks_api_compress_getnest" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/compress.py", + "source_location": "L51", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_compress_rationale_51", + "target": "stocks_api_compress_getnest" + }, { "relation": "calls", "context": "call", @@ -69972,6 +70248,56 @@ "source": "stocks_api_compress_compressresponse", "target": "stocks_api_compress_fixheaders" }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/frame.py", + "source_location": "L17", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_stocks_api_frame_py", + "target": "stocks_api_frame_optimizedtypes" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/frame.py", + "source_location": "L37", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_stocks_api_frame_py", + "target": "stocks_api_frame_arrowtypefor" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/frame.py", + "source_location": "L48", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_stocks_api_frame_py", + "target": "stocks_api_frame_sortcacheframe" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/frame.py", + "source_location": "L58", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_stocks_api_frame_py", + "target": "stocks_api_frame_buildtickerindex" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/frame.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_frame_rationale_1", + "target": "main_app_stocks_api_frame_py" + }, { "relation": "imports_from", "context": "import", @@ -73172,6 +73498,16 @@ "source": "controller_stocksapi_controller_gethistorical", "target": "controller_stocksapi_controller_rationale_65" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L173", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_173", + "target": "controller_stocksapi_controller_getfundamental" + }, { "relation": "rationale_for", "confidence": "EXTRACTED", @@ -73293,6 +73629,16 @@ "source": "controller_stocksapi_controller_getfundamental", "target": "controller_stocksapi_controller_rationale_123" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L247", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_247", + "target": "controller_stocksapi_controller_getcotations" + }, { "relation": "rationale_for", "confidence": "EXTRACTED", @@ -73414,6 +73760,16 @@ "source": "controller_stocksapi_controller_getcotations", "target": "controller_stocksapi_controller_rationale_184" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L307", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_307", + "target": "controller_stocksapi_controller_getlivecotation" + }, { "relation": "rationale_for", "confidence": "EXTRACTED", @@ -78224,6 +78580,16 @@ "source": "agents_md", "target": "server_agents_architecture" }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L47", + "weight": 1.0, + "confidence_score": 1.0, + "source": "agents_md", + "target": "server_agents_code_style" + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -85074,6 +85440,88 @@ "source": "specs_2026_09_29_nginx_scaling_design_4_topology", "target": "specs_2026_09_29_nginx_scaling_design_codeblock_1" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L51", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_build_rationale_51", + "target": "stocks_api_build_runtimeconf" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/build.py", + "source_location": "L47", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_build_rationale_47", + "target": "stocks_api_build_runtimeconf" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L71", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_cache_buildfeathercache", + "target": "stocks_api_cache_optimizedtypes" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L124", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_cache_buildfeathercache", + "target": "stocks_api_cache_arrowtypefor" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L59", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_cache_rationale_59", + "target": "stocks_api_cache_arrowtypefor" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L91", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_cache_rationale_91", + "target": "stocks_api_cache_trybuildlock" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L171", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_cache_rationale_171", + "target": "stocks_api_cache_sortcacheframe" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/stocks_api/cache.py", + "source_location": "L191", + "weight": 1.0, + "confidence_score": 1.0, + "source": "stocks_api_cache_rationale_191", + "target": "stocks_api_cache_buildtickerindex" + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -150482,5 +150930,5 @@ "label": "User Authentication & Authorization" } ], - "built_at_commit": "e7ac74321e9dd166254cd676f1c5658310676ca5" + "built_at_commit": "9cfa467f5e182a4a67ff4017297a51199f520f60" } \ No newline at end of file diff --git a/graphify-out/manifest.json b/graphify-out/manifest.json index 90b9dca6..371c8037 100644 --- a/graphify-out/manifest.json +++ b/graphify-out/manifest.json @@ -280,8 +280,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\scraper_b3\\scraper.py": { - "mtime": 1790713506.6574717, - "ast_hash": "e7e449234b41094827a1bc2b43178561", + "mtime": 1790736245.276425, + "ast_hash": "860f0d9a1a74c9b33fadce5148077f58", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\scraper_b3\\xango.py": { @@ -289,14 +289,24 @@ "ast_hash": "0cbeed2304027b45b74b36f17b47cca7", "semantic_hash": "" }, + "D:\\Repositories\\server\\main\\app\\stocks_api\\build.py": { + "mtime": 1790735995.475924, + "ast_hash": "2f3a5ebbac44760ca137dfe855401ce7", + "semantic_hash": "" + }, "D:\\Repositories\\server\\main\\app\\stocks_api\\cache.py": { - "mtime": 1790724655.0228858, - "ast_hash": "388139c59bea2be15ee4f8b0c88ed5f0", + "mtime": 1790741669.473623, + "ast_hash": "ce8f5980b1bb0d6bd9da37a5a1a73c6b", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\stocks_api\\compress.py": { - "mtime": 1790724898.1914341, - "ast_hash": "5727624a2e4a0ff71d6712bc5a6a612d", + "mtime": 1790739970.4316273, + "ast_hash": "40cae8759ccb6e11c3ce10131f491b7f", + "semantic_hash": "" + }, + "D:\\Repositories\\server\\main\\app\\stocks_api\\frame.py": { + "mtime": 1790731677.1945455, + "ast_hash": "3abe607fb233c15354d453ba78344d4e", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\stocks_api\\key.py": { @@ -305,18 +315,18 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\stocks_api\\query.py": { - "mtime": 1790715582.5629618, - "ast_hash": "c07116fa51c154d741c5c5fd01486714", + "mtime": 1790739880.705703, + "ast_hash": "f8b84a54eb57b5732d93cd6ca5c2827e", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\stocks_api\\sync_cache.py": { - "mtime": 1790723901.4459727, - "ast_hash": "ccb5104dfcd8d85e68fb42602486f1a1", + "mtime": 1790736142.4061236, + "ast_hash": "9f07874bea2f9fcfad9acd239ae7b84e", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\stocks_api\\util.py": { - "mtime": 1789365853.1977775, - "ast_hash": "f25300eb19b8346657c558af17425018", + "mtime": 1790739970.4316273, + "ast_hash": "f471cd66ad245dbf12e0331e38491c99", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\user\\user.py": { @@ -335,8 +345,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\controller\\stocksapi_controller.py": { - "mtime": 1790723781.080048, - "ast_hash": "b9abf6a7b19fa64a64cc5d4386b15687", + "mtime": 1790728596.5079153, + "ast_hash": "ec0651a956b330f5c56040b66ac01ac2", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\controller\\user_controller.py": { @@ -530,8 +540,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\AGENTS.md": { - "mtime": 1789627715.7268107, - "ast_hash": "ef6021079152d1189a4168e43670caa3", + "mtime": 1790741297.0454617, + "ast_hash": "cc31d96c7adf30b7561b742615300842", "semantic_hash": "" }, "D:\\Repositories\\server\\docker-compose.yml": { diff --git a/main/app/scraper_b3/scraper.py b/main/app/scraper_b3/scraper.py index b5d4d2ab..f0b2e9dd 100644 --- a/main/app/scraper_b3/scraper.py +++ b/main/app/scraper_b3/scraper.py @@ -26,13 +26,9 @@ warnings.filterwarnings("ignore", category=RuntimeWarning) -SAFE_COLUMN_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9 _]*$") - - def getCurrentSelic(): - selic = pd.DataFrame( - requests.get("https://api.bcb.gov.br/dados/serie/bcdata.sgs.4189/dados?formato=json", timeout=30).json() - ) + selic = pd.DataFrame(requests.get("https://api.bcb.gov.br/dados/serie/bcdata.sgs.4189/dados?formato=json", timeout=30).json()) + selic["valor"] = selic["valor"].astype(float) selic["valor medio 10y"] = selic["valor"].rolling(120, min_periods=120).mean().round(2) @@ -612,7 +608,7 @@ def exportMysql(self, df): for col in existingCols if any(pattern in col for pattern in historicalPatterns) and col not in JSON_COLUMNS ] - historicalCols = [col for col in historicalCols if SAFE_COLUMN_RE.match(col) is not None] + historicalCols = [col for col in historicalCols if re.compile(r"^[A-Za-z0-9][A-Za-z0-9 _]*$").match(col) is not None] if historicalCols: conn.execute(