amsdal_crm 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. amsdal_crm-0.1.0/.amsdal/.environment +1 -0
  2. amsdal_crm-0.1.0/.amsdal-cli +11 -0
  3. amsdal_crm-0.1.0/.github/workflows/ci.yml +77 -0
  4. amsdal_crm-0.1.0/.github/workflows/release.yml +99 -0
  5. amsdal_crm-0.1.0/.github/workflows/tag_check.yml +29 -0
  6. amsdal_crm-0.1.0/.gitignore +38 -0
  7. amsdal_crm-0.1.0/CLAUDE.md +105 -0
  8. amsdal_crm-0.1.0/PKG-INFO +68 -0
  9. amsdal_crm-0.1.0/README.md +50 -0
  10. amsdal_crm-0.1.0/RELEASE.md +180 -0
  11. amsdal_crm-0.1.0/amsdal_crm/__about__.py +1 -0
  12. amsdal_crm-0.1.0/amsdal_crm/__init__.py +13 -0
  13. amsdal_crm-0.1.0/amsdal_crm/app.py +25 -0
  14. amsdal_crm-0.1.0/amsdal_crm/constants.py +13 -0
  15. amsdal_crm-0.1.0/amsdal_crm/errors.py +21 -0
  16. amsdal_crm-0.1.0/amsdal_crm/fixtures/__init__.py +1 -0
  17. amsdal_crm-0.1.0/amsdal_crm/fixtures/permissions.py +29 -0
  18. amsdal_crm-0.1.0/amsdal_crm/fixtures/pipelines.py +74 -0
  19. amsdal_crm-0.1.0/amsdal_crm/lifecycle/__init__.py +1 -0
  20. amsdal_crm-0.1.0/amsdal_crm/lifecycle/consumer.py +44 -0
  21. amsdal_crm-0.1.0/amsdal_crm/migrations/0000_initial.py +633 -0
  22. amsdal_crm-0.1.0/amsdal_crm/models/__init__.py +46 -0
  23. amsdal_crm-0.1.0/amsdal_crm/models/account.py +127 -0
  24. amsdal_crm-0.1.0/amsdal_crm/models/activity.py +140 -0
  25. amsdal_crm-0.1.0/amsdal_crm/models/attachment.py +43 -0
  26. amsdal_crm-0.1.0/amsdal_crm/models/contact.py +132 -0
  27. amsdal_crm-0.1.0/amsdal_crm/models/custom_field_definition.py +44 -0
  28. amsdal_crm-0.1.0/amsdal_crm/models/deal.py +172 -0
  29. amsdal_crm-0.1.0/amsdal_crm/models/pipeline.py +28 -0
  30. amsdal_crm-0.1.0/amsdal_crm/models/stage.py +47 -0
  31. amsdal_crm-0.1.0/amsdal_crm/models/workflow_rule.py +44 -0
  32. amsdal_crm-0.1.0/amsdal_crm/services/__init__.py +15 -0
  33. amsdal_crm-0.1.0/amsdal_crm/services/activity_service.py +56 -0
  34. amsdal_crm-0.1.0/amsdal_crm/services/custom_field_service.py +143 -0
  35. amsdal_crm-0.1.0/amsdal_crm/services/deal_service.py +131 -0
  36. amsdal_crm-0.1.0/amsdal_crm/services/email_service.py +118 -0
  37. amsdal_crm-0.1.0/amsdal_crm/services/workflow_service.py +177 -0
  38. amsdal_crm-0.1.0/amsdal_crm/settings.py +26 -0
  39. amsdal_crm-0.1.0/amsdal_ml/Third-Party Materials - AMSDAL Dependencies - License Notices.md +2094 -0
  40. amsdal_crm-0.1.0/config.yml +20 -0
  41. amsdal_crm-0.1.0/license_check.py +38 -0
  42. amsdal_crm-0.1.0/pyproject.toml +168 -0
  43. amsdal_crm-0.1.0/scripts/release.sh +18 -0
  44. amsdal_crm-0.1.0/scripts/tag_check.sh +50 -0
  45. amsdal_crm-0.1.0/tests/conftest.py +27 -0
  46. amsdal_crm-0.1.0/tests/integration/__init__.py +0 -0
  47. amsdal_crm-0.1.0/tests/integration/conftest.py +213 -0
  48. amsdal_crm-0.1.0/tests/integration/services/__init__.py +1 -0
  49. amsdal_crm-0.1.0/tests/integration/services/test_deal_service.py +309 -0
  50. amsdal_crm-0.1.0/tests/integration/services/test_email_service.py +239 -0
  51. amsdal_crm-0.1.0/tests/integration/services/test_workflow_service.py +63 -0
  52. amsdal_crm-0.1.0/tests/unit/__init__.py +0 -0
  53. amsdal_crm-0.1.0/tests/unit/conftest.py +227 -0
  54. amsdal_crm-0.1.0/tests/unit/lifecycle/__init__.py +1 -0
  55. amsdal_crm-0.1.0/tests/unit/lifecycle/test_consumer.py +175 -0
  56. amsdal_crm-0.1.0/tests/unit/models/__init__.py +1 -0
  57. amsdal_crm-0.1.0/tests/unit/models/test_account.py +455 -0
  58. amsdal_crm-0.1.0/tests/unit/models/test_activity.py +253 -0
  59. amsdal_crm-0.1.0/tests/unit/models/test_contact.py +160 -0
  60. amsdal_crm-0.1.0/tests/unit/models/test_deal.py +234 -0
  61. amsdal_crm-0.1.0/tests/unit/models/test_pipeline.py +33 -0
  62. amsdal_crm-0.1.0/tests/unit/models/test_remaining.py +373 -0
  63. amsdal_crm-0.1.0/tests/unit/models/test_stage.py +56 -0
  64. amsdal_crm-0.1.0/tests/unit/services/__init__.py +1 -0
  65. amsdal_crm-0.1.0/tests/unit/services/test_activity_service.py +290 -0
  66. amsdal_crm-0.1.0/tests/unit/services/test_custom_field_service.py +232 -0
  67. amsdal_crm-0.1.0/tests/unit/services/test_deal_service.py +487 -0
  68. amsdal_crm-0.1.0/tests/unit/services/test_email_service.py +269 -0
  69. amsdal_crm-0.1.0/tests/unit/services/test_workflow_service.py +457 -0
  70. amsdal_crm-0.1.0/tests/unit/test_app.py +120 -0
  71. amsdal_crm-0.1.0/tests/unit/test_constants.py +172 -0
  72. amsdal_crm-0.1.0/tests/unit/test_errors.py +274 -0
  73. amsdal_crm-0.1.0/tests/unit/test_settings.py +197 -0
  74. amsdal_crm-0.1.0/uv.lock +3689 -0
@@ -0,0 +1 @@
1
+ main
@@ -0,0 +1,11 @@
1
+ {
2
+ "src_dir": "amsdal_crm",
3
+ "config_path": "./config.yml",
4
+ "http_port": 8080,
5
+ "check_model_exists": true,
6
+ "json_indent": 4,
7
+ "application_uuid": "a114e90e97aa544988f5d9e099b10173",
8
+ "application_name": "amsdal-crm",
9
+ "models_format": "py",
10
+ "is_plugin": true
11
+ }
@@ -0,0 +1,77 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+
6
+ jobs:
7
+ license-check:
8
+ name: License check
9
+ runs-on: self-hosted
10
+ steps:
11
+ - name: Reset permissions
12
+ run: |
13
+ sudo chown -R $(id -u):$(id -g) .
14
+ - uses: actions/checkout@v5
15
+
16
+ - name: Python install
17
+ uses: actions/setup-python@v6
18
+ with:
19
+ python-version: "3.11"
20
+ - name: License check
21
+ run: |
22
+ pip install toml
23
+ python license_check.py
24
+
25
+ test-lint:
26
+ name: Run tests and check style (Python ${{ matrix.python-version }}, ${{ matrix.database-backend }})
27
+ needs: [license-check]
28
+ runs-on: self-hosted
29
+ strategy:
30
+ max-parallel: 1
31
+ fail-fast: false
32
+ matrix:
33
+ python-version: ["3.11", "3.12"]
34
+ database-backend: ["sqlite", "postgres"]
35
+ services:
36
+ postgres:
37
+ image: pgvector/pgvector:pg16
38
+ env:
39
+ POSTGRES_USER: postgres
40
+ POSTGRES_PASSWORD: example
41
+ POSTGRES_DB: postgres
42
+ ports:
43
+ - 5432:5432
44
+ options: >-
45
+ --health-cmd pg_isready
46
+ --health-interval 10s
47
+ --health-timeout 5s
48
+ --health-retries 5
49
+ env:
50
+ PYTHON: ${{ matrix.python-version }}
51
+ DEPS: yes
52
+ _TYPER_FORCE_DISABLE_TERMINAL: true
53
+ steps:
54
+ - uses: actions/checkout@v5
55
+ - uses: szenius/set-timezone@v2.0
56
+ with:
57
+ timezoneLinux: "EEST"
58
+
59
+ - name: Set up python
60
+ uses: actions/setup-python@v6
61
+ with:
62
+ python-version: ${{ matrix.python-version }}
63
+
64
+ - name: Hatch and UV setup
65
+ run: |
66
+ pip install --upgrade uv hatch==1.14.2
67
+ hatch env prune
68
+ hatch env create
69
+ hatch run sync
70
+
71
+ - name: Run style checks
72
+ if: always() && matrix.database-backend == 'sqlite'
73
+ run: hatch run all
74
+
75
+ - name: Run tests
76
+ if: always()
77
+ run: hatch run cov tests/ -- --database_backend=${{ matrix.database-backend }}
@@ -0,0 +1,99 @@
1
+ name: CD
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
7
+
8
+ jobs:
9
+ license-check:
10
+ name: License check
11
+ runs-on: self-hosted
12
+ steps:
13
+ - uses: actions/checkout@v5
14
+
15
+ - name: Python install
16
+ uses: actions/setup-python@v6
17
+ with:
18
+ python-version: "3.11"
19
+ - name: License check
20
+ run: |
21
+ pip install toml
22
+ python license_check.py
23
+
24
+ build:
25
+ name: Build and compile
26
+ needs: [license-check]
27
+ runs-on: self-hosted
28
+ strategy:
29
+ fail-fast: false
30
+ matrix:
31
+ python-version: [ "3.10" ]
32
+ env:
33
+ PYTHON: ${{ matrix.python-version }}
34
+ DEPS: yes
35
+
36
+ steps:
37
+ - uses: actions/checkout@v5
38
+
39
+ - name: Set up python
40
+ uses: actions/setup-python@v6
41
+ with:
42
+ python-version: ${{ matrix.python-version }}
43
+
44
+ - name: Install hatch
45
+ run: |
46
+ python -m pip install --upgrade setuptools
47
+ python -m pip install hatch==1.14.2
48
+
49
+ - name: Build
50
+ run: hatch build
51
+
52
+ - name: Store the distribution packages
53
+ uses: actions/upload-artifact@v4
54
+ with:
55
+ name: python-package-distributions
56
+ path: dist/
57
+
58
+ publish:
59
+ name: Publish to PyPi
60
+ runs-on: self-hosted
61
+ needs: build
62
+ strategy:
63
+ fail-fast: false
64
+ matrix:
65
+ python-version: [ "3.10" ]
66
+ steps:
67
+ - name: Set up python
68
+ uses: actions/setup-python@v6
69
+ with:
70
+ python-version: ${{ matrix.python-version }}
71
+
72
+ - name: Download all the dists
73
+ uses: actions/download-artifact@v4
74
+ with:
75
+ name: python-package-distributions
76
+ path: dist/
77
+
78
+ - name: Branch info
79
+ id: branch_info
80
+ run: |
81
+ echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/}
82
+
83
+ - name: Install hatch
84
+ run: |
85
+ python -m pip install --upgrade setuptools
86
+ python -m pip install hatch==1.14.2
87
+
88
+ - name: Publish
89
+ run: |
90
+ hatch publish --user ${{ secrets.PYPI_USERNAME }} --auth ${{ secrets.PYPI_TOKEN }}
91
+
92
+ - name: Create Release
93
+ uses: softprops/action-gh-release@v2
94
+ with:
95
+ body_path: latest-changelogs.md
96
+ files: dist/*
97
+ name: ${{ steps.branch_info.outputs.SOURCE_TAG }}
98
+ draft: false
99
+ prerelease: false
@@ -0,0 +1,29 @@
1
+ name: Tags Check
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - main
7
+ types: [closed]
8
+
9
+
10
+ jobs:
11
+ tags_check:
12
+ name: Tags Check
13
+ if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main' && startsWith(github.event.pull_request.head.ref, 'release/')
14
+ runs-on: self-hosted
15
+ steps:
16
+ - uses: actions/checkout@v5
17
+ with:
18
+ token: ${{ secrets.ACCESS_KEY }}
19
+
20
+ - name: Install jq
21
+ run: |
22
+ sudo apt-get update
23
+ sudo apt-get install -y jq
24
+
25
+ - name: Create tag
26
+ env:
27
+ GITHUB_TOKEN: ${{ secrets.ACCESS_KEY }}
28
+ run: |
29
+ bash ./scripts/tag_check.sh
@@ -0,0 +1,38 @@
1
+ .venv/
2
+ venv/
3
+ /warehouse
4
+ .python-version
5
+
6
+ __pycache__/
7
+ *.py[cod]
8
+ *.pyo
9
+ *.pyd
10
+
11
+ .pytest_cache/
12
+ .coverage
13
+ .coverage.*
14
+ htmlcov/
15
+ .mypy_cache/
16
+ .ruff_cache/
17
+
18
+ build/
19
+ dist/
20
+ *.egg-info/
21
+
22
+ .vscode/
23
+ .idea/
24
+ *.code-workspace
25
+ .DS_Store
26
+ Thumbs.db
27
+
28
+ .env
29
+ .env.*
30
+ !.env.example
31
+
32
+
33
+ /transactions/
34
+ /migrations/
35
+ /models/
36
+ /fixtures/
37
+ /static/
38
+ .tmp
@@ -0,0 +1,105 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ amsdal-crm is a CRM plugin for the AMSDAL Framework that provides CRM models similar to Salesforce ones. It supports both synchronous and asynchronous modes, with primary focus on async operations.
8
+
9
+ ## Development Commands
10
+
11
+ ### Environment Setup
12
+ ```bash
13
+ # Install dependencies using hatch/uv
14
+ pip install --upgrade uv hatch==1.14.2
15
+ hatch env create
16
+ hatch run sync
17
+ ```
18
+
19
+ ### Testing
20
+ ```bash
21
+ # Run all tests with coverage
22
+ hatch run cov
23
+
24
+ # Run specific test file
25
+ hatch run test tests/unit/models/test_activity.py
26
+
27
+ # Run tests with pytest directly (after env setup)
28
+ pytest tests/
29
+ pytest tests/unit/models/ # Run unit tests for models
30
+
31
+ ```
32
+
33
+ ### Code Quality
34
+ ```bash
35
+ # Run all checks (style + typing)
36
+ hatch run all
37
+
38
+ # Style checks only
39
+ hatch run style
40
+
41
+ # Format code (fix style issues)
42
+ hatch run fmt
43
+
44
+ # Type checking
45
+ hatch run typing
46
+ ```
47
+
48
+ ### Dependency Management
49
+ ```bash
50
+ # Sync dependencies
51
+ hatch run sync
52
+
53
+ # Update lock file
54
+ hatch run lock
55
+
56
+ # Upgrade all dependencies
57
+ hatch run lock-upgrade
58
+ ```
59
+
60
+ ### AMSDAL CLI Commands
61
+ ```bash
62
+ # Generate new model
63
+ amsdal generate model ModelName --format py
64
+
65
+ # Generate property for model
66
+ amsdal generate property --model ModelName property_name
67
+
68
+ # Generate transaction
69
+ amsdal generate transaction TransactionName
70
+
71
+ # Generate hook
72
+ amsdal generate hook --model ModelName on_create
73
+ ```
74
+
75
+ ## Architecture
76
+
77
+ ## Code Style
78
+
79
+ - Python 3.11+ required
80
+ - Uses Ruff for linting and formatting with 120-char line length
81
+ - Single quotes enforced (`quote-style = "single"`)
82
+ - Import ordering: force-single-line with order-by-type
83
+ - Type checking via mypy with strict settings (disallow_any_generics, check_untyped_defs)
84
+ - Excludes migrations directory from linting
85
+
86
+ ## Testing
87
+
88
+ - Uses pytest with pytest-asyncio for async tests
89
+ - Test fixtures in `tests/conftest.py` provide mocked OpenAI clients
90
+ - Coverage tracking with coverage.py
91
+
92
+ ## CI/CD
93
+
94
+ The project uses self-hosted runners with two jobs:
95
+ 1. **license-check**: Validates third-party licenses using `license_check.py`
96
+ 2. **test-lint**: Runs on Python 3.11 and 3.12, executes `hatch run all` (style+typing) and `hatch run cov`
97
+
98
+ ## Key Patterns
99
+
100
+ 1. **Async-First**: Most components prioritize async methods; sync methods often raise NotImplementedError
101
+ 2. **Abstract Base Classes**: Heavy use of ABCs to define interfaces for models, retrievers, ingesters, and agents
102
+ 3. **Configuration via Pydantic**: Settings loaded from environment with type validation
103
+ 4. **AMSDAL Integration**: Uses AMSDAL's model system, manager, and connection framework
104
+ 5. **Chunking Strategy**: Text split into chunks with metadata preservation for better embedding quality
105
+ 6. **Tag-Based Filtering**: Embeddings tagged for fine-grained retrieval control
@@ -0,0 +1,68 @@
1
+ Metadata-Version: 2.4
2
+ Name: amsdal_crm
3
+ Version: 0.1.0
4
+ Summary: amsdal-crm plugin for AMSDAL Framework
5
+ Requires-Python: >=3.11
6
+ Requires-Dist: aiohttp==3.12.15
7
+ Requires-Dist: amsdal-cli>=0.5.7
8
+ Requires-Dist: amsdal-data>=0.5.9
9
+ Requires-Dist: amsdal-models>=0.5.9
10
+ Requires-Dist: amsdal-utils>=0.5.4
11
+ Requires-Dist: amsdal>=0.5.6
12
+ Requires-Dist: mcp>=0.1
13
+ Requires-Dist: openai==1.100.2
14
+ Requires-Dist: pydantic-settings~=2.12
15
+ Requires-Dist: pydantic~=2.12
16
+ Requires-Dist: pymupdf>=1.24.10
17
+ Description-Content-Type: text/markdown
18
+
19
+ # amsdal-crm
20
+
21
+ This plugin provides custom models, properties, transactions, and hooks for the AMSDAL Framework.
22
+
23
+ ## Plugin Structure
24
+
25
+ - `src/models/` - Contains model definitions in Python format
26
+ - `src/transactions/` - Contains transaction definitions
27
+ - `pyproject.toml` - Plugin configuration file
28
+ - `config.yml` - Configuration for connections
29
+
30
+ ## Installing this Plugin
31
+
32
+ To use this plugin in an AMSDAL application:
33
+
34
+ 1. Copy the plugin directory to your AMSDAL application
35
+ 2. Import the models and transactions as needed
36
+ 3. Register the plugin in your application configuration
37
+
38
+ ## Development
39
+
40
+ This plugin uses sync mode.
41
+
42
+ ### Adding Models
43
+
44
+ ```bash
45
+ amsdal generate model ModelName --format py
46
+ ```
47
+
48
+ ### Adding Properties
49
+
50
+ ```bash
51
+ amsdal generate property --model ModelName property_name
52
+ ```
53
+
54
+ ### Adding Transactions
55
+
56
+ ```bash
57
+ amsdal generate transaction TransactionName
58
+ ```
59
+
60
+ ### Adding Hooks
61
+
62
+ ```bash
63
+ amsdal generate hook --model ModelName on_create
64
+ ```
65
+
66
+ ## Testing
67
+
68
+ Test your plugin by integrating it with an AMSDAL application and running the application's test suite.
@@ -0,0 +1,50 @@
1
+ # amsdal-crm
2
+
3
+ This plugin provides custom models, properties, transactions, and hooks for the AMSDAL Framework.
4
+
5
+ ## Plugin Structure
6
+
7
+ - `src/models/` - Contains model definitions in Python format
8
+ - `src/transactions/` - Contains transaction definitions
9
+ - `pyproject.toml` - Plugin configuration file
10
+ - `config.yml` - Configuration for connections
11
+
12
+ ## Installing this Plugin
13
+
14
+ To use this plugin in an AMSDAL application:
15
+
16
+ 1. Copy the plugin directory to your AMSDAL application
17
+ 2. Import the models and transactions as needed
18
+ 3. Register the plugin in your application configuration
19
+
20
+ ## Development
21
+
22
+ This plugin uses sync mode.
23
+
24
+ ### Adding Models
25
+
26
+ ```bash
27
+ amsdal generate model ModelName --format py
28
+ ```
29
+
30
+ ### Adding Properties
31
+
32
+ ```bash
33
+ amsdal generate property --model ModelName property_name
34
+ ```
35
+
36
+ ### Adding Transactions
37
+
38
+ ```bash
39
+ amsdal generate transaction TransactionName
40
+ ```
41
+
42
+ ### Adding Hooks
43
+
44
+ ```bash
45
+ amsdal generate hook --model ModelName on_create
46
+ ```
47
+
48
+ ## Testing
49
+
50
+ Test your plugin by integrating it with an AMSDAL application and running the application's test suite.
@@ -0,0 +1,180 @@
1
+ # Release Guide
2
+
3
+ Follow these steps each time you release a new version of `amsdal-crm`.
4
+
5
+ ---
6
+
7
+ ## Step 0: Check Working Directory
8
+
9
+ Before starting, ensure you have a clean working directory:
10
+
11
+ ```bash
12
+ git status
13
+ ```
14
+
15
+ **If you have uncommitted changes:**
16
+ 1. Review the changes: `git diff`
17
+ 2. Decide what to do:
18
+ - **Commit them now** if they should be part of this release:
19
+ ```bash
20
+ git add .
21
+ git commit -m "Your commit message"
22
+ git push origin main
23
+ ```
24
+ - **Stash them** if they're unrelated to this release:
25
+ ```bash
26
+ git stash
27
+ # After release, restore with: git stash pop
28
+ ```
29
+ - **Discard them** if they're not needed:
30
+ ```bash
31
+ git restore . # Be careful - this cannot be undone!
32
+ ```
33
+
34
+ ---
35
+
36
+ ## Step 1: Update Version Number
37
+
38
+ Edit `amsdal_crm/__about__.py`:
39
+
40
+ ```python
41
+ __version__ = '0.1.4' # Change to your new version
42
+ ```
43
+
44
+ **Version format**: `MAJOR.MINOR.PATCH`
45
+ - PATCH: Bug fixes (e.g., `0.1.3` → `0.1.4`)
46
+ - MINOR: New features (e.g., `0.1.4` → `0.2.0`)
47
+ - MAJOR: Breaking changes (e.g., `0.2.0` → `1.0.0`)
48
+
49
+ ---
50
+
51
+ ## Step 2: Update Changelogs
52
+
53
+ ### 2a. Update `latest-changelogs.md`
54
+
55
+ Replace entire content with your new release notes:
56
+
57
+ ```markdown
58
+ ## [v0.1.4](https://pypi.org/project/amsdal_ml/0.1.4/) - 2025-10-15
59
+
60
+ ### Description of changes
61
+
62
+ - First change
63
+ - Second change
64
+ - Third change
65
+ ```
66
+
67
+ ### 2b. Update `change-logs.md`
68
+
69
+ Prepend the same content to the top of the file (keep existing entries below).
70
+
71
+ ---
72
+
73
+ ## Step 3: Run Quality Checks
74
+
75
+ ```bash
76
+ hatch run all
77
+ hatch run cov
78
+ ```
79
+
80
+ All checks must pass before continuing.
81
+
82
+ ---
83
+
84
+ ## Step 4: Create Release Branch
85
+
86
+ ```bash
87
+ git checkout -b release/v0.1.4
88
+ ```
89
+
90
+ ---
91
+
92
+ ## Step 5: Commit and Push
93
+
94
+ ```bash
95
+ git add amsdal_crm/__about__.py latest-changelogs.md change-logs.md
96
+ git commit -m "Release v0.1.4"
97
+ git push origin release/v0.1.4
98
+ ```
99
+
100
+ ---
101
+
102
+ ## Step 6: Create Pull Request
103
+
104
+ 1. Go to: https://github.com/amsdal/amsdal_crm/pulls
105
+ 2. Click "New pull request"
106
+ 3. Set base: `main` ← compare: `release/v0.1.4`
107
+ 4. Title: `Release v0.1.4`
108
+ 5. Add description with changelog content
109
+ 6. Create and merge the PR
110
+
111
+ ---
112
+
113
+ ## Step 7: Checkout Main and Pull
114
+
115
+ ```bash
116
+ git checkout main
117
+ git pull origin main
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Step 8: Create and Push Tag
123
+
124
+ ```bash
125
+ git tag -a v0.1.4 -m "Release v0.1.4"
126
+ git push origin v0.1.4
127
+ ```
128
+
129
+ **Important**: Tag must start with `v` (e.g., `v0.1.4`)
130
+
131
+ ---
132
+
133
+ ## Step 9: Monitor CI/CD
134
+
135
+ Go to: https://github.com/amsdal/amsdal_crm/actions
136
+
137
+ Wait for all jobs to complete:
138
+ 1. ✅ License check
139
+ 2. ✅ Build
140
+ 3. ✅ Publish to PyPI
141
+ 4. ✅ Create GitHub release
142
+
143
+ ---
144
+
145
+ ## Step 10: Verify Release
146
+
147
+ ### Check PyPI
148
+ https://pypi.org/project/amsdal_crm/
149
+
150
+ ### Check GitHub Releases
151
+ https://github.com/amsdal/amsdal_crm/releases
152
+
153
+ ### Test Installation
154
+ ```bash
155
+ pip install --upgrade amsdal-crm
156
+ python -c "import amsdal_ml; print(amsdal_crm.__version__)"
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Done! ✅
162
+
163
+ ---
164
+
165
+ ## Troubleshooting
166
+
167
+ **If CI fails:**
168
+ 1. Check logs at https://github.com/amsdal/amsdal_crm/actions
169
+ 2. Fix the issue
170
+ 3. Delete and recreate the tag:
171
+ ```bash
172
+ git tag -d v0.1.4
173
+ git push origin :refs/tags/v0.1.4
174
+ git tag -a v0.1.4 -m "Release v0.1.4"
175
+ git push origin v0.1.4
176
+ ```
177
+
178
+ **If you need to rollback:**
179
+ - Release a new patch version with the fix (recommended)
180
+ - Or yank the release from PyPI using `twine`
@@ -0,0 +1 @@
1
+ __version__ = '0.1.0'
@@ -0,0 +1,13 @@
1
+ """AMSDAL CRM Plugin.
2
+
3
+ A minimal MVP CRM plugin providing core CRM functionality including:
4
+ - Contact and Account management
5
+ - Deal pipeline management
6
+ - Activity tracking and timeline
7
+ - Custom fields support
8
+ - Basic workflow automation
9
+ - Email integration
10
+ - File attachments
11
+ """
12
+
13
+ __version__ = '0.1.0'
@@ -0,0 +1,25 @@
1
+ """CRM App Configuration."""
2
+
3
+ from amsdal.contrib.app_config import AppConfig
4
+ from amsdal_utils.lifecycle.enum import LifecycleEvent
5
+ from amsdal_utils.lifecycle.producer import LifecycleProducer
6
+
7
+ from amsdal_crm.constants import CRMLifecycleEvent
8
+
9
+
10
+ class CRMAppConfig(AppConfig):
11
+ """Configuration for the CRM application."""
12
+
13
+ def on_ready(self) -> None:
14
+ """Set up CRM lifecycle listeners and initialize module."""
15
+ from amsdal_crm.lifecycle.consumer import DealWonNotificationConsumer
16
+ from amsdal_crm.lifecycle.consumer import LoadCRMFixturesConsumer
17
+
18
+ # Load fixtures on startup
19
+ LifecycleProducer.add_listener(LifecycleEvent.ON_SERVER_STARTUP, LoadCRMFixturesConsumer)
20
+
21
+ # Custom CRM events
22
+ LifecycleProducer.add_listener(CRMLifecycleEvent.ON_DEAL_WON, DealWonNotificationConsumer) # type: ignore[arg-type]
23
+
24
+ # Additional event listeners can be added here
25
+ # LifecycleProducer.add_listener(CRMLifecycleEvent.ON_DEAL_LOST, DealLostNotificationConsumer)