Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Changelog

All notable changes to this project are documented here.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- Google Customer Match now sends a plain-text `countryCode` in `addressInfo`, so country
participates in address matching (while Meta continues to receive the hashed country column).
- Accurate Google partial-failure accounting: `recordsAccepted` / `recordsRejected` are now derived
from the parsed `partialFailureError.details`, instead of counting the whole batch as accepted.
- ESLint (type-aware) + Prettier, wired into CI alongside typecheck, tests, and build.
- `CONTRIBUTING.md` and this `CHANGELOG.md`.

## [1.0.0] - 2026-06-28

### Added

- Initial release of **AudienceSync** — secure, in-memory Reverse ETL.
- Source extraction from PostgreSQL, MySQL, and Stripe for a configurable time window.
- Platform-correct PII normalization (email, phone → E.164, name, country, zip) and SHA-256 hashing,
performed entirely in memory with no disk writes.
- Meta Custom Audience and Google Customer Match uploaders with configurable batch sizes and
exponential-backoff retries on transient (429 / 5xx) failures.
- Google OAuth2 refresh-token exchange for unattended cron runs.
- `commander` CLI with `sync`, `schedule`, and `config` subcommands, plus a `node-cron` scheduler.
- Strict TypeScript with branded PII types and a vitest test suite for the normalizer.
- GitHub Actions CI across Node 18, 20, and 22.

[Unreleased]: https://github.com/NagaYu/audiencesync/compare/v1.0.0...HEAD
[1.0.0]: https://github.com/NagaYu/audiencesync/releases/tag/v1.0.0
77 changes: 77 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Contributing to AudienceSync

Thanks for your interest in improving AudienceSync! This project handles customer PII, so we hold
contributions to a high bar for correctness and security. Please read this before opening a PR.

## Ground rules

1. **Never log raw PII.** Emails, phone numbers, and names must only ever exist in memory as
transient values and leave the process exclusively as SHA-256 digests. Logs may contain counts
and batch status — never identifiers.
2. **No disk writes for customer data.** No CSV, temp file, or staging table. The in-memory,
file-free guarantee is the whole point of the tool.
3. **Keep it strict.** `tsc --strict` must pass with zero errors. Prefer the branded PII types in
[`src/types.ts`](src/types.ts) so raw values can't flow where a hash is expected.

## Development setup

Requires Node.js >= 18.17.

```bash
git clone https://github.com/NagaYu/audiencesync.git
cd audiencesync
npm install
```

### Everyday commands

```bash
npm run dev # tsup watch mode
npm run typecheck # tsc --noEmit, strict
npm run lint # ESLint (type-aware); npm run lint:fix to autofix
npm run format # Prettier write; npm run format:check to verify
npm test # vitest
npm run build # production bundle → dist/
```

Before pushing, make sure all of these are green:

```bash
npm run typecheck && npm run lint && npm run format:check && npm test && npm run build
```

CI runs the same checks across Node 18, 20, and 22.

## Project layout

```text
src/
├── types.ts # strict shared types + branded PII primitives
├── normalizer.ts # pure in-memory cleansing + SHA-256 hashing
├── extractor.ts # Postgres / MySQL / Stripe extraction
├── sync.ts # Meta + Google batched uploaders
└── index.ts # commander CLI + node-cron scheduler
test/
├── normalizer.test.ts
└── sync.test.ts
```

## Pull request expectations

- **One logical change per PR.** Keep diffs reviewable.
- **Add or update tests** for any behavior change. Pure logic (normalization, batching, parsing)
should have unit tests in `test/`.
- **Update docs** (README / this file / `.env.example`) when you change configuration or behavior.
- **Conventional-ish commit subjects** are appreciated (`feat:`, `fix:`, `chore:`, `docs:`), and
reference the issue you're closing (`Closes #N`).
- **Update [`CHANGELOG.md`](CHANGELOG.md)** under an `Unreleased` heading for user-facing changes.

## Reporting security issues

If you find a vulnerability — especially anything that could expose PII — please do **not** open a
public issue. Email the maintainers privately so it can be addressed before disclosure.

## License

By contributing, you agree that your contributions will be licensed under the
[MIT License](LICENSE).
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,9 @@ src/
## 🤝 Contributing

Issues and PRs are welcome. Please keep `npm run typecheck`, `npm run lint`, and `npm test` green,
run `npm run format` before committing, and never log raw PII.
run `npm run format` before committing, and never log raw PII. See
[CONTRIBUTING.md](CONTRIBUTING.md) for the full guide and [CHANGELOG.md](CHANGELOG.md) for the
release history.

---

Expand Down
Loading