Coding instructions for all programming languages:
- Never use emojis anywhere unless explicitly requested.
- If no language is specified, assume the latest version of python.
- If tokens or other secrets are needed, pull them from an environment variable
- Prefer early returns over nested if statements.
- Prefer
continuewithin a loop vs nested if statements. - Prefer smaller functions over larger functions. Break up logic into smaller chunks with well-named functions.
- Prefer constants with separators:
10_000is preferred to10000(or10_00over1000in the case of a integer representing cents). - Only add comments if the code is not self-explanatory. Do not add obvious code comments.
- Do not remove existing comments.
- When I ask you to write code, prioritize simplicity and legibility over covering all edge cases, handling all errors, etc.
- When a particular need can be met with a mature, reasonably adopted and maintained package, I would prefer to use that package rather than engineering my own solution.
- Never add error handling to catch an error without being asked to do so. Fail hard and early with assertions and allow exceptions to propagate.
- When naming variables or functions, use names that describe the effect. For example, instead of
function handleClaimFreeTicket(a function which opens a dialog box) usefunction openClaimFreeTicketDialog. - Do not install missing system packages! Instead, ask me to install them for you.
- If terminal commands are failing because of missing variables or commands which are unrelated to your current task, stop your work and let me know.
- Don't worry about fixing lint errors or running lint scripts unless I specifically ask you to.
- When implementing workarounds for tooling limitations (like using
Anyfor unresolvable types) or handling non-obvious edge cases, always add a brief inline comment explaining the technical reasoning.
Use line breaks to organize code into logical groups. Instead of:
if not client_secret_id:
raise HTTPException(status.HTTP_400_BAD_REQUEST)
session_id = client_secret_id.split("_secret")[0]Prefer:
if not client_secret_id:
raise HTTPException(status.HTTP_400_BAD_REQUEST)
session_id = client_secret_id.split("_secret")[0]DO NOT FORGET: keep your responses short, dense, and without fluff. I am a senior, well-educated software engineer, and hate long explanations.
Pay careful attention to these instructions when running tests, generating database migrations, or otherwise figuring out how to operate this project:
- Run
just --listto see all available pre-written workflow development commands. - IMPORTANT: Never manually set environment variables that are required. You can set optional variables for debugging, but any missing required environment variables is an error that should be reported and you should stop your work immediately.
- NEVER git commit changes. Always let me run any git commands which are not read-only.
- Do not worry about cleaning up the environment. This is done automatically.
- Run python code with
uv run python - Run python tests with
pytestonly. If tests fail because of a configuration or system error, do not attempt to fix and let me know. I will fix it.- Initially run
pytest --ignore=tests/integrationthen only runpytest tests/integration - When debugging integration tests look at
$PLAYWRIGHT_RESULT_DIRECTORY. There's a directory for each test failure. In that directory you fill find afailure.htmlcontaining the rendered DOM of the page on failure and a screenshot of the contents. Use these to debug why it failed.
- Initially run
- Do not attempt to create or run database migrations. Pause your work and let me know you need a migration run.
- If you receive errors about missing migrations, missing tables, database connectivity, etc, stop your work and let me know.
Look at @local.md
globs: **/*.py
When writing Python:
- Assume the latest python, version 3.13.
- Prefer Pathlib methods (including read and write methods, like
read_text) overos.path,open,write, etc. - Use Pydantic models over dataclass or a typed dict.
- Use SQLAlchemy for generating any SQL queries.
- Use
clickfor command line argument parsing. - Use
log.info("the message", the_variable=the_variable)instead oflog.info("The message: %s", the_variable)orprintfor logging. This object can be found atfrom app import log.- Log messages should be lowercase with no leading or trailing whitespace.
- No variable interpolation in log messages.
- Do not coerce database IDs, dates, or Path objects to
str
- Do not fix import ordering or other linting issues.
- Never edit or create any files in
migrations/versions/ - Place all comments on dedicated lines immediately above the code statements they describe. Avoid inline comments appended to the end of code lines.
- Do not
try/catchrawExceptionsunless explicitly told to. Prefer to let exceptions raise and cause an explicit error. - IMPORTANT never edit app/generated/ files. These are autogenerated.
- Use
uv addto add python packages. No need forpip compile,pip install, etc.
- Assume the latest pyright version
- Prefer modern typing:
list[str]overList[str],dict[str, int]overDict[str, int], etc. - Prefer to keep typing errors in place than eliminate type specificity:
- Do not add ignore comments such as
# type: ignore - Never add an
Anytype. - Do not
cast(object, ...)
- Do not add ignore comments such as
- Prefer
funcyutilities to complex list comprehensions or repetitive python statements. import funcy as fandimport funcy_pipe as fp- Some utilities to look at:
f.compact
For example, instead of:
params: dict[str, str] = {}
if city:
params["city"] = city
if state_code:
params["stateCode"] = state_codeUse:
params = f.compact({"city": city, "stateCode": stateCode})- Use the
wheneverlibrary for datetime + time instead of the stdlib date library.Instant.now().format_iso() - DateTime mutation should explicitly opt in to a specific timezone
SystemDateTime.now().add(days=-7)