A minimal Django app for form submission and review. The Django project lives under efile_app/ with settings in efile_app/efile/.
- Requirements
- Python 3.10+
- uv
-
0) Install uv (one-time)
- macOS (Homebrew):
brew install uv
- Or official installer:
curl -LsSf https://astral.sh/uv/install.sh | sh
- macOS (Homebrew):
-
1) Sync dependencies From the project root (this will create
.venv/and install deps frompyproject.toml):uv sync
-
2) Initialize the database
cd efile_app uv run python manage.py migrate --run-syncdb -
3) Run the development server
uv run python manage.py runserver
Then open http://127.0.0.1:8000/login in your browser.
uv sync creates .venv/. You can activate it and run Django commands normally:
-
macOS/Linux:
source .venv/bin/activate cd efile_app python manage.py migrate --run-syncdb python manage.py runserver
-
Windows (PowerShell):
.venv\Scripts\Activate.ps1 cd efile_app python manage.py migrate --run-syncdb python manage.py runserver
Deactivate with deactivate when you're done.
-
Create an admin user
- With uv:
uv run python manage.py createsuperuser
Admin will be available at
/admin/after you start the server. - With uv:
-
Static files During development, static files are served automatically. No
collectstaticis needed.
The application uses AWS S3 for document storage and file uploads. Follow these steps to set up your S3 bucket:
- Log into the AWS Console and navigate to S3
- Create a new bucket (e.g.,
forms-mvp-your-suffix) - Choose your preferred region (default:
us-east-1) - Initially, turn off "Block all public access" in the S3 bucket settings. We will need this off initially so that the bucket policy can be applied. After we have created the bucket policy, we will block all public access by toggling back on "Block all public access".
- Tags can be created to help track ownership of resources and is useful for cost tracking, environment tracking, etc.
- Default encryption settings should be fine
Apply this bucket policy to allow public read access for Tyler to download documents:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*"
}
]
}Replace YOUR-BUCKET-NAME with your actual bucket name.
Create an IAM user with the following policy for application access:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::YOUR-BUCKET-NAME"
}
]
}You can now turn on "Block all public access" in the S3 bucket settings. Go to Permissions. Click on the Edit button in the "Block public access (bucket settings)" section. Toggle on "Block all public access". Click "Save Changes" and confirm the action.
This will keep the existing policy, which we use to generate the pre-signed URLs to Tyler access, but restrict the files from being made publicly accessible in other ways.
Copy the example environment file and update the S3 settings:
cp efile_app/.env.example efile_app/.envEdit efile_app/.env with your AWS credentials:
# AWS S3 Configuration
AWS_ACCESS_KEY_ID = "your-aws-access-key-id-here"
AWS_SECRET_ACCESS_KEY = "your-aws-secret-access-key-here"
AWS_S3_BUCKET_NAME = "your-bucket-name-here"
AWS_S3_REGION_NAME = "us-east-1"Note: The application generates pre-signed URLs for secure document access, so there's no need to make your S3 bucket public. The bucket policy above allows Tyler's systems to download documents when needed.
Ruff is configured in pyproject.toml under [tool.ruff].
- Using uv
- Install dev tools:
uv sync --group dev
- Lint the codebase:
uv run ruff check . - Auto-format (optional):
uv run ruff format .
- Install dev tools:
Notes: Ruff targets Python 3.10, line length 120, and excludes Django migrations (**/migrations/*).
Pytest is configured via pyproject.toml to use pytest-django.
-
Install dev deps (once):
uv sync --group dev
-
Run all tests (from project root):
pytest -q
-
Select tests:
pytest efile_app/efile/ -q # only the efile app pytest -k "login and not slow" -q # expression match pytest efile_app/efile/tests/test_smoke.py::test_login_page_renders -q
-
Speed tips:
pytest --reuse-db -q # keep the test DB between runs pytest -n auto -q # run in parallel (pytest-xdist)
-
Coverage (optional):
pytest --cov=efile_app --cov-report=term-missing
Notes:
DJANGO_SETTINGS_MODULEis set toefile.settingsin[tool.pytest.ini_options].- Tests are discovered under
efile_app/. An example smoke test lives atefile_app/efile/tests/test_smoke.py.
Playwright tests are located in efile_app/tests/ and provide browser-based testing of the complete user workflow. These are intended to be run manually and are not part of the CI/CD pipeline because they produce
side-effects (e.g. filing new cases in EFSP) and rely on external APIs (e.g. EFSP again). The tests stop short
of the document upload step as that would touch S3. We also wanted to avoid filing new cases into Tyler as part
of the current end-to-end testing.
-
Install Playwright dependencies (one-time):
cd efile_app npm install npx playwright install -
Environment variables: Create a
.envfile in theefile_app/directory with:E2E_TEST_USERNAME=your_test_email@example.com E2E_TEST_PASSWORD=your_test_password E2E_TEST_BASE_URL=http://localhost:8000 # optional, defaults to localhost:8000
The Playwright configuration includes several important settings:
- Global Setup: Automatically loads environment variables and validates credentials before running tests
- Timeout: Extended to 10 minutes (600,000ms) to accommodate form filling and external API calls
- Base URL: Configured for
http://localhost:8000(Django development server) - Retry Strategy: 2 retries on CI, 0 retries locally
- Parallel Execution: Disabled on CI (1 worker) to avoid conflicts with external services
- Browser: Currently configured for Chromium only (Firefox and Safari commented out)
-
Start the Django server first:
cd efile_app uv run python manage.py runserver -
Run all Playwright tests:
cd efile_app npx playwright test
-
Run specific tests:
cd efile_app npx playwright test tests/expert-form-name-change.spec.js npx playwright test tests/expert-form-order-of-protection.spec.js npx playwright test tests/expert-form-forfeiture-of-seized-property.spec.js
-
Run with UI mode (interactive):
cd efile_app npx playwright test --ui
-
Run in headed mode (see browser):
cd efile_app npx playwright test --headed
Note: The global setup automatically validates your .env configuration before running tests. If environment variables are missing, tests will fail with a clear error message.
The Playwright tests use a modular architecture with shared utilities:
tests/setup.js: Global setup that loads environment variables and validates credentials before any tests runtests/test-utils.js: Shared utilities includingloginViaLogout(),loginViaLoginPage(), andgetTestConfig()functionsplaywright.config.js: Playwright configuration with global setup enabled, extended timeout, and CI-specific settings
The test-utils.js module provides two login methods:
loginViaLogout(page, config): Logs in via the/logoutendpoint (ensures clean session) - this is the defaultloginViaLoginPage(page, config): Logs in via the/loginpageloginUser(page, config): Alias forloginViaLogout()for backward compatibility
expert-form-name-change.spec.js: Tests the complete workflow for filing a name change caseexpert-form-order-of-protection.spec.js: Tests the complete workflow for filing an order of protection caseexpert-form-forfeiture-of-seized-property.spec.js: Tests the complete workflow for filing a forfeiture of seized property case
All tests:
- Use shared login utilities from
test-utils.js - Navigate to the appropriate expert form section
- Fill out court selection and case details
- Complete required party information
- Verify the document upload page loads correctly
- Take screenshots for visual verification
Screenshots are saved to screenshots/ directory and excluded from git via .gitignore.
Ty (a Rust-based type checker) is configured in pyproject.toml under [tool.ty.src].
-
Run a one-off check:
uv run ty check
-
Watch mode (re-run on changes):
uv run ty watch
Pre-commit hooks are configured in .pre-commit-config.yaml to run Ruff formatting/linting and type checking on commits, plus tests on push.
-
Install pre-commit hooks (one-time setup):
uv run pre-commit install uv run pre-commit install --hook-type pre-push
-
Run hooks manually:
uv run pre-commit run --all-files # run all hooks on all files uv run pre-commit run pytest # run just the pytest hook
Note: The pytest hook runs on pre-push stage to keep commits fast. If you skip the pre-push hook installation, tests won't run automatically before pushing.
efile_app/manage.py— Django management scriptefile_app/efile/settings.py— Project settings (uses SQLite by default; DB file atefile_app/db.sqlite3)efile_app/efile/urls.py— URL routingefile_app/efile/templates/— HTML templatesefile_app/efile/static/— Static assets
- Default settings run with
DEBUG=Trueand SQLite for local development.