Initial scaffold: Shopify recesso (withdrawal) compliance app

- Remix (TypeScript) + Polaris, official Shopify app template
- Prisma multi-tenant schema (Settings, ExclusionRule, WithdrawalRequest, AuditLog, WebhookEvent) on Postgres
- Mandatory GDPR compliance webhooks (data_request, redact, shop/redact) + HMAC handlers
- API version pinned 2026-04, scopes read_orders/read_products
- Fly deploy config; two-env strategy (custom now, public later)
- Dev setup: shopify.web.toml + Vite allowedHosts for tunnels
- Docs: PLAN.md, ANALISI-REQUISITI-LEGALI.md (Art. 54-bis compliance)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mv83a29B4eFv5ixoj6PoE1
This commit is contained in:
2026-07-06 18:02:17 +02:00
commit 4586b2e557
62 changed files with 2968 additions and 0 deletions

1
app/.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1 @@
* @shop/dev_experience

73
app/.github/CODE_OF_CONDUCT.md vendored Normal file
View File

@@ -0,0 +1,73 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at opensource@shopify.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct/
[homepage]: https://www.contributor-covenant.org

41
app/.github/CONTRIBUTING.md vendored Normal file
View File

@@ -0,0 +1,41 @@
# How to contribute
The Shopify Remix app template is an open source project. We want to make it as easy and transparent as possible to contribute. If we are missing anything or can make the process easier in any way, please let us know by [opening an issue](https://github.com/Shopify/shopify-app-template-remix/issues/new).
## Code of conduct
We expect all participants to read our [code of conduct](https://github.com/Shopify/shopify-app-template-remix/.github/CODE_OF_CONDUCT.md) to understand which actions are and arent tolerated.
## Open development
All work on the Shopify Remix app template happens directly on GitHub. Both team members and external contributors send pull requests which go through the same review process.
## Bugs
### Where to find known issues
We track all of our issues in GitHub and [bugs](https://github.com/Shopify/shopify-app-template-remix/labels/Bug) are labeled accordingly. If you are planning to work on an issue, avoid ones which already have an assignee, where someone has commented within the last two weeks they are working on it, or the issue is labeled with [fix in progress](https://github.com/Shopify/shopify-app-template-remix/labels/fix%20in%20progress). We will do our best to communicate when an issue is being worked on internally.
### Reporting new issues
To reduce duplicates, look through open issues before filing one. When [opening an issue](https://github.com/Shopify/shopify-app-template-remix/issues/new?template=ISSUE.md), complete as much of the template as possible.
## Your first pull request
Working on your first pull request? You can learn how from this free video series:
[How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)
To help you get familiar with our contribution process, we have a list of [good first issues](https://github.com/Shopify/shopify-app-template-remix/labels/good%20first%20issue) that contain bugs with limited scope. This is a great place to get started.
If you decide to fix an issue, please check the comment thread in case somebody is already working on a fix. If nobody is working on it, leave a comment stating that you intend to work on it.
If somebody claims an issue but doesnt follow up for more than two weeks, its fine to take it over but still leave a comment stating that you intend to work on it.
### Sending a pull request
Well review your pull request and either merge it, request changes to it, or close it with an explanation. Well do our best to provide updates and feedback throughout the process.
### Contributor License Agreement (CLA)
Each contributor is required to [sign a CLA](https://cla.shopify.com/). This process is automated as part of your first pull request and is only required once. If any contributor has not signed or does not have an associated GitHub account, the CLA check will fail and the pull request is unable to be merged.

46
app/.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,46 @@
---
name: '🐛 Bug Report'
about: Something isn't working
labels: 'Type: Bug 🐛'
---
# Issue summary
Before opening this issue, I have:
- [ ] Upgraded to the latest version of the `@shopify` packages
- Affected `@shopify/shopify-*` package and version:
- Node version:
- Operating system:
- [ ] Set `{ logger: { level: LogSeverity.Debug } }` in my configuration
- [ ] Found a reliable way to reproduce the problem that indicates it's a problem with the package
- [ ] Looked for similar issues in this repository
- [ ] Checked that this isn't an issue with a Shopify API
- If it is, please create a post in the [Shopify community forums](https://community.shopify.com/c/partners-and-developers/ct-p/appdev) or report it to [Shopify Partner Support](https://help.shopify.com/en/support/partners/org-select)
<!--
Write a short description of the issue here.
We can only fix issues for which there is a clear reproduction scenario.
The more context you can provide, the easier it becomes for us to investigate and fix the issue.
-->
## Expected behavior
What do you think should happen?
## Actual behavior
What actually happens?
## Steps to reproduce the problem
1.
1.
1.
## Debug logs
```
// Paste any relevant logs here
```

34
app/.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,34 @@
<!--
How to write a good PR title:
- Prefix it with [Feature] (if applicable)
- Start with a verb, for example: Add, Delete, Improve, Fix…
- Give as much context as necessary and as little as possible
- Prefix it with [WIP] while its a work in progress
-->
### WHY are these changes introduced?
Fixes #0000 <!-- link to issue if one exists -->
<!--
Context about the problem thats being addressed.
-->
### WHAT is this pull request doing?
<!--
Summary of the changes committed.
Before / after screenshots appreciated for UI changes.
-->
### Test this PR
```bash
shopify app init --template=https://github.com/Shopify/shopify-app-template-remix#<your-branch-name>
```
### Checklist
- [ ] I have made changes to the `README.md` file and other related documentation, if applicable
- [ ] I have added an entry to `CHANGELOG.md`
- [ ] I'm aware I need to create a new release when this PR is merged

58
app/.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,58 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
# Enable version updates for npm
- package-ecosystem: 'npm'
# Look for `package.json` and `lock` files in the `root` directory
directory: '/'
# Check the npm registry for updates every day (weekdays)
schedule:
interval: 'weekly'
# Dependabot defaults to 5 open pull requests at a time
open-pull-requests-limit: 100
# Cooldown is the number of days after a release to wait until opening a PR
# This gives us more confidence changes can be merged because changes have been community tested.
# See: https://github.blog/changelog/2025-07-01-dependabot-supports-configuration-of-a-minimum-package-age/
cooldown:
default-days: 14
semver-major-days: 30
semver-minor-days: 14
semver-patch-days: 14
groups:
# Group together PRs of dependant packages
prisma:
patterns:
- 'prisma'
- '@prisma/client'
react:
patterns:
- 'react'
- 'react-dom'
- '@types/react'
- '@types/react-dom'
vite:
patterns:
- 'vite'
- 'vite-tsconfig-paths'
remix:
patterns:
- '@remix-run/dev'
- '@remix-run/fs-routes'
- '@remix-run/node'
- '@remix-run/react'
- '@remix-run/eslint-config'
- '@remix-run/route-config'
# Group all patch updates not accounted for in prior groups in a single PR.
# This reduces the number of PRs to review and rebase.
patch-updates:
patterns:
- "*"
update-types:
- "patch"

18
app/.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
on: [push, pull_request]
name: CI
jobs:
CI:
name: CI_Node_${{ matrix.version }}
runs-on: ubuntu-latest
strategy:
matrix:
version: [20.19.0, 22, 24]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version: ${{ matrix.version }}
- name: Install
run: yarn install

22
app/.github/workflows/cla.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: Contributor License Agreement (CLA)
on:
pull_request_target:
types: [opened, synchronize]
issue_comment:
types: [created]
jobs:
cla:
runs-on: ubuntu-latest
if: |
(github.event.issue.pull_request
&& !github.event.issue.pull_request.merged_at
&& contains(github.event.comment.body, 'signed')
)
|| (github.event.pull_request && !github.event.pull_request.merged)
steps:
- uses: Shopify/shopify-cla-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
cla-token: ${{ secrets.CLA_TOKEN }}

View File

@@ -0,0 +1,20 @@
name: Close Waiting for Response Issues
on:
schedule:
- cron: "30 1 * * *"
workflow_dispatch:
jobs:
check-need-info:
runs-on: ubuntu-latest
steps:
- name: close-issues
uses: actions-cool/issues-helper@45d75b6cf72bf4f254be6230cb887ad002702491 # v3.6.3
with:
actions: "close-issues"
token: ${{ secrets.GITHUB_TOKEN }}
labels: "Waiting for Response"
inactive-day: 14
body: |
We are closing this issue because we did not hear back regarding additional details we needed to resolve this issue. If the issue persists and you are able to provide the missing clarification we need, you can respond here or create a new issue.
We appreciate your understanding as we try to manage our number of open issues.

99
app/.github/workflows/convert-to-js.yml vendored Normal file
View File

@@ -0,0 +1,99 @@
name: Create Javascript conversion PR
on:
push:
branches:
- main
workflow_dispatch:
jobs:
convert-ts-files:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
- name: Create lock file
run: touch yarn.lock
- name: Setup Node.js
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version: 22.12.x
cache: 'yarn'
- name: Install dependencies
run: yarn add -W --dev @shopify/eslint-plugin --ignore-engines
- name: Create temporary tsconfig file
run: |
echo '{
"include": ["./app/**/*", "*.ts", "*.tsx", ".graphqlrc.ts"],
"compilerOptions": {
"strict": true,
"removeComments": false,
"skipLibCheck": true,
"isolatedModules": true,
"noEmitOnError": true,
"jsx": "preserve",
"module": "ES2022",
"moduleResolution": "bundler",
"target": "ES2022",
"paths": {
"~/*": ["./app/*"]
}
}
}' > tsconfig.js.json
- name: Transpile to Javascript
run: yarn tsc -p tsconfig.js.json
- name: Remove Typescript files
run: |
find app \( -name "*.ts" -o -name "*.tsx" \) -delete
find . \( -name ".graphqlrc.ts" -o -name "tsconfig.js.json" -o -name "vite.config.ts" \) -delete
- name: Run prettier
run: yarn prettier -w "app/**/*.{js,jsx}" ".graphqlrc.js" "vite.config.js"
- name: Run ESLint
run: |
yarn lint "app/**/*.{js,jsx}" ".graphqlrc.js" "vite.config.js" --fix --no-cache --ignore-pattern "\!.graphqlrc.js" --plugin @shopify/eslint-plugin --rule '{
"import/order": "error",
"import/newline-after-import": "error",
"padding-line-between-statements": ["error",
{ "blankLine": "always", "prev": ["const", "let", "var"], "next": "*"},
{ "blankLine": "any", "prev": ["const", "let", "var"], "next": ["const", "let", "var"]}
{ "blankLine": "always", "prev": "*", "next": "return" },
{ "blankLine": "always", "prev": "*", "next": "export" },
{ "blankLine": "never", "prev": "export", "next": "export" },
{ "blankLine": "always", "prev": "*", "next": "block-like" },
{ "blankLine": "always", "prev": "block-like", "next": "*" }
]}'
- name: Prepare files for git
run: |
git config user.name GitHub
git config user.email noreply@github.com
git fetch
git restore --staged package.json
git restore package.json
- name: Stage changes to files
run: |
git add .
git checkout -b temp_javascript_updates
git commit -m "Convert template to Javascript"
git checkout javascript
git pull
git checkout -
git rebase -m -X theirs javascript
git push -f origin temp_javascript_updates:javascript_updates
- name: Create Javascript PR
run: |
gh pr view --json mergedAt -q ".mergedAt" javascript_updates | grep -E "^$" || \
gh pr create -B javascript -H javascript_updates --title 'Convert template to Javascript' --body 'This is an automated PR that converts the latest changes from Typescript to Javascript'
env:
GH_TOKEN: ${{ github.token }}

View File

@@ -0,0 +1,15 @@
name: Remove Waiting Labels
on:
issue_comment:
types: [created]
workflow_dispatch:
jobs:
remove-labels-on-activity:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
- uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 # v1.2.0
if: contains(github.event.issue.labels.*.name, 'Waiting for Response')
with:
labels: |
Waiting for Response