openehr-rails 0.2.2 → 0.4.0
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.
- checksums.yaml +5 -5
- data/.devcontainer/Dockerfile +17 -0
- data/.devcontainer/devcontainer.json +13 -0
- data/.dockerignore +12 -0
- data/.github/workflows/ci.yml +75 -0
- data/.github/workflows/release.yml +31 -0
- data/.gitignore +5 -2
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +106 -0
- data/CLAUDE.md +77 -0
- data/Guardfile +70 -0
- data/LICENSE +194 -0
- data/README.md +194 -0
- data/Rakefile +7 -0
- data/app/controllers/openehr_rails/application_controller.rb +44 -0
- data/app/controllers/openehr_rails/ehrs_controller.rb +29 -0
- data/app/controllers/openehr_rails/fhir_controller.rb +148 -0
- data/app/controllers/openehr_rails/openehr_api/compositions_controller.rb +122 -0
- data/app/controllers/openehr_rails/openehr_api/ehrs_controller.rb +87 -0
- data/app/controllers/openehr_rails/queries_controller.rb +61 -0
- data/app/controllers/openehr_rails/templates_controller.rb +75 -0
- data/app/views/layouts/openehr_rails/application.html.erb +39 -0
- data/app/views/openehr_rails/ehrs/index.html.erb +27 -0
- data/app/views/openehr_rails/ehrs/show.html.erb +55 -0
- data/app/views/openehr_rails/queries/show.html.erb +103 -0
- data/app/views/openehr_rails/templates/index.html.erb +132 -0
- data/config/routes.rb +47 -0
- data/demo_assets/demo_seed.rb +91 -0
- data/demo_assets/templates/bmi_calculation.opt +1751 -0
- data/demo_assets/templates/patient_blood_pressure.opt +1465 -0
- data/demo_assets/templates/problem_list.opt +858 -0
- data/doc/DEMO_ja.md +459 -0
- data/doc/HANDOFF_openehr_aql_create_from_json.md +165 -0
- data/doc/HANDOFF_openehr_factory_missing_type.md +193 -0
- data/doc/HANDOFF_openehr_opt_parser.md +146 -0
- data/docker/demo.Dockerfile +59 -0
- data/docker/docker-compose.yml +12 -0
- data/gemfiles/rails_7_2.gemfile +5 -0
- data/gemfiles/rails_8_0.gemfile +5 -0
- data/gemfiles/rails_8_1.gemfile +5 -0
- data/lib/generators/openehr/fhir_profile/fhir_profile_generator.rb +38 -0
- data/lib/generators/openehr/install/install_generator.rb +54 -8
- data/lib/generators/openehr/install/templates/initializers/openehr.rb +53 -0
- data/lib/generators/openehr/install/templates/migrations/create_openehr_ehrs.rb +16 -0
- data/lib/generators/openehr/install/templates/migrations/create_openehr_rm_storage.rb +86 -0
- data/lib/generators/openehr/install/templates/migrations/create_openehr_rm_versioning.rb +28 -0
- data/lib/generators/openehr/install/templates/migrations/create_openehr_templates.rb +14 -0
- data/lib/generators/openehr/install/templates/models/openehr_template.rb +3 -0
- data/lib/generators/openehr/scaffold/scaffold_generator.rb +231 -197
- data/lib/generators/openehr/scaffold/templates/controller.rb.erb +78 -0
- data/lib/generators/openehr/scaffold/templates/locale.yml.erb +9 -0
- data/lib/generators/openehr/scaffold/templates/migration.rb.erb +18 -0
- data/lib/generators/openehr/scaffold/templates/model.rb.erb +15 -0
- data/lib/generators/openehr/scaffold/templates/request_spec.rb.erb +46 -0
- data/lib/generators/openehr/scaffold/templates/views/_form.html.erb +23 -0
- data/lib/generators/openehr/scaffold/templates/views/edit.html.erb +6 -0
- data/lib/generators/openehr/scaffold/templates/views/index.html.erb +29 -0
- data/lib/generators/openehr/scaffold/templates/views/new.html.erb +5 -0
- data/lib/generators/openehr/scaffold/templates/views/show.html.erb +11 -0
- data/lib/openehr-rails/version.rb +1 -1
- data/lib/openehr-rails.rb +3 -3
- data/lib/openehr_rails/aql/dataset_adapter.rb +46 -0
- data/lib/openehr_rails/aql/errors.rb +19 -0
- data/lib/openehr_rails/aql/executor.rb +29 -0
- data/lib/openehr_rails/aql/query_validator.rb +122 -0
- data/lib/openehr_rails/aql_queryable.rb +50 -0
- data/lib/openehr_rails/engine.rb +9 -0
- data/lib/openehr_rails/fhir/capability_statement.rb +49 -0
- data/lib/openehr_rails/fhir/deserializer.rb +80 -0
- data/lib/openehr_rails/fhir/profile_generator.rb +137 -0
- data/lib/openehr_rails/fhir/profile_repository.rb +40 -0
- data/lib/openehr_rails/fhir/resource_registry.rb +89 -0
- data/lib/openehr_rails/fhir/serializer.rb +88 -0
- data/lib/openehr_rails/fhir/type_map.rb +61 -0
- data/lib/openehr_rails/naming.rb +23 -0
- data/lib/openehr_rails/opt/field_extractor.rb +270 -0
- data/lib/openehr_rails/opt/parser.rb +52 -0
- data/lib/openehr_rails/opt/remote_fetcher.rb +136 -0
- data/lib/openehr_rails/opt.rb +9 -0
- data/lib/openehr_rails/release_check.rb +134 -0
- data/lib/openehr_rails/rm/canonical_serializer.rb +95 -0
- data/lib/openehr_rails/rm/composition.rb +49 -0
- data/lib/openehr_rails/rm/composition_committer.rb +68 -0
- data/lib/openehr_rails/rm/contribution.rb +41 -0
- data/lib/openehr_rails/rm/data_value.rb +70 -0
- data/lib/openehr_rails/rm/data_values.rb +182 -0
- data/lib/openehr_rails/rm/ehr.rb +20 -0
- data/lib/openehr_rails/rm/ehr_serializer.rb +52 -0
- data/lib/openehr_rails/rm/graph_builder.rb +194 -0
- data/lib/openehr_rails/rm/graph_persister.rb +63 -0
- data/lib/openehr_rails/rm/node.rb +44 -0
- data/lib/openehr_rails/rm/nodes.rb +36 -0
- data/lib/openehr_rails/rm/rm_object_builder.rb +217 -0
- data/lib/openehr_rails/rm/type_map.rb +69 -0
- data/lib/openehr_rails/rm/version.rb +34 -0
- data/lib/openehr_rails/rm.rb +46 -0
- data/lib/openehr_rails/runtime_scaffolder.rb +73 -0
- data/lib/openehr_rails/storable.rb +238 -0
- data/lib/openehr_rails/template_importer.rb +45 -0
- data/lib/openehr_rails/template_registry.rb +63 -0
- data/lib/openehr_rails/template_uploader.rb +68 -0
- data/lib/openehr_rails.rb +91 -0
- data/lib/tasks/release_check.rake +17 -0
- data/openehr-rails.gemspec +26 -12
- data/script/build_demo.sh +129 -0
- data/script/build_starter.sh +156 -0
- data/spec/generators/openehr/fhir_profile/fhir_profile_generator_spec.rb +30 -0
- data/spec/generators/openehr/fhir_profile/remote_fhir_profile_generator_spec.rb +43 -0
- data/spec/generators/openehr/install/install_generator_spec.rb +43 -3
- data/spec/generators/openehr/scaffold/opt_scaffold_generator_spec.rb +127 -0
- data/spec/generators/openehr/scaffold/remote_opt_scaffold_generator_spec.rb +52 -0
- data/spec/generators/templates/bmi_calculation.opt +1751 -0
- data/spec/generators/templates/openEHR-EHR-OBSERVATION.blood_pressure.v1.adl +21 -2912
- data/spec/models/openehr_template_spec.rb +114 -0
- data/spec/openehr_rails/aql/dataset_adapter_spec.rb +57 -0
- data/spec/openehr_rails/aql/executor_spec.rb +53 -0
- data/spec/openehr_rails/aql/model_api_spec.rb +28 -0
- data/spec/openehr_rails/aql/query_validator_spec.rb +77 -0
- data/spec/openehr_rails/authentication_spec.rb +141 -0
- data/spec/openehr_rails/fhir/profile_generator_spec.rb +85 -0
- data/spec/openehr_rails/fhir/serializer_spec.rb +125 -0
- data/spec/openehr_rails/naming_spec.rb +20 -0
- data/spec/openehr_rails/opt/field_extractor_concept_slug_spec.rb +56 -0
- data/spec/openehr_rails/opt/field_extractor_ordinal_spec.rb +107 -0
- data/spec/openehr_rails/opt/field_extractor_section_spec.rb +69 -0
- data/spec/openehr_rails/opt/field_extractor_spec.rb +115 -0
- data/spec/openehr_rails/opt/remote_fetcher_spec.rb +106 -0
- data/spec/openehr_rails/release_check_spec.rb +82 -0
- data/spec/openehr_rails/rm/aql_graph_spec.rb +57 -0
- data/spec/openehr_rails/rm/canonical_serializer_spec.rb +77 -0
- data/spec/openehr_rails/rm/composition_committer_spec.rb +81 -0
- data/spec/openehr_rails/rm/composition_spec.rb +64 -0
- data/spec/openehr_rails/rm/create_from_json_roundtrip_spec.rb +131 -0
- data/spec/openehr_rails/rm/data_value_spec.rb +85 -0
- data/spec/openehr_rails/rm/ehr_serializer_spec.rb +37 -0
- data/spec/openehr_rails/rm/graph_builder_spec.rb +62 -0
- data/spec/openehr_rails/rm/graph_persister_spec.rb +93 -0
- data/spec/openehr_rails/rm/node_spec.rb +63 -0
- data/spec/openehr_rails/rm/rm_object_builder_spec.rb +76 -0
- data/spec/openehr_rails/rm/type_map_spec.rb +34 -0
- data/spec/openehr_rails/runtime_scaffolder_spec.rb +49 -0
- data/spec/openehr_rails/storable_spec.rb +131 -0
- data/spec/openehr_rails/storable_spec_model.rb +18 -0
- data/spec/openehr_rails/template_importer_spec.rb +50 -0
- data/spec/openehr_rails/template_uploader_spec.rb +50 -0
- data/spec/spec_helper.rb +8 -8
- data/spec/support/active_record.rb +177 -0
- data/spec/templates/bmi_calculation_without_uid.opt +1748 -0
- data/spec/templates/sample_blood_pressure.opt +48 -0
- data/spec/unit/opt_parser_spec.rb +47 -0
- data/spec/unit/require_smoke_spec.rb +25 -0
- data/templates/openehr_template.rb +89 -0
- metadata +235 -77
- data/README.rdoc +0 -33
- data/doc/README_FOR_APP +0 -2
- data/lib/generators/openehr/assets/assets_generator.rb +0 -28
- data/lib/generators/openehr/assets/templates/javascript.js +0 -1
- data/lib/generators/openehr/assets/templates/stylesheet.css.scss +0 -3
- data/lib/generators/openehr/controller/controller_generator.rb +0 -17
- data/lib/generators/openehr/controller/templates/controller.rb +0 -74
- data/lib/generators/openehr/helper/helper_generator.rb +0 -17
- data/lib/generators/openehr/helper/templates/helper.rb +0 -2
- data/lib/generators/openehr/i18n/i18n_generator.rb +0 -49
- data/lib/generators/openehr/i18n/templates/i18n.rb +0 -6
- data/lib/generators/openehr/i18n/templates/language.yml +0 -15
- data/lib/generators/openehr/install/templates/i18n.rb +0 -8
- data/lib/generators/openehr/migration/migration_generator.rb +0 -32
- data/lib/generators/openehr/migration/templates/archetypes.rb +0 -10
- data/lib/generators/openehr/migration/templates/rms.rb +0 -16
- data/lib/generators/openehr/model/model_generator.rb +0 -118
- data/lib/generators/openehr/model/templates/activemodel.rb +0 -71
- data/lib/generators/openehr/model/templates/archetype.rb +0 -3
- data/lib/generators/openehr/model/templates/rm.rb +0 -3
- data/lib/generators/openehr/scaffold/templates/_form.html.erb +0 -19
- data/lib/generators/openehr/scaffold/templates/application.html.erb +0 -14
- data/lib/generators/openehr/scaffold/templates/application_controller.rb +0 -3
- data/lib/generators/openehr/scaffold/templates/edit.html.erb +0 -6
- data/lib/generators/openehr/scaffold/templates/index.html.erb +0 -28
- data/lib/generators/openehr/scaffold/templates/inflections.rb +0 -3
- data/lib/generators/openehr/scaffold/templates/layout.css.scss +0 -4
- data/lib/generators/openehr/scaffold/templates/new.html.erb +0 -5
- data/lib/generators/openehr/scaffold/templates/route.rb +0 -2
- data/lib/generators/openehr/scaffold/templates/routes.rb +0 -2
- data/lib/generators/openehr/scaffold/templates/show.html.erb +0 -6
- data/lib/generators/openehr.rb +0 -60
- data/lib/rcomponents.rb +0 -48
- data/spec/generator_helper.rb +0 -4
- data/spec/generators/openehr/archetyped_base_spec.rb +0 -40
- data/spec/generators/openehr/assets/assets_generator_spec.rb +0 -37
- data/spec/generators/openehr/controller/controller_generator_spec.rb +0 -25
- data/spec/generators/openehr/helper/helper_generator_spec.rb +0 -23
- data/spec/generators/openehr/i18n/i18n_generator_spec.rb +0 -61
- data/spec/generators/openehr/migration/migration_generator_spec.rb +0 -27
- data/spec/generators/openehr/model/model_generator_spec.rb +0 -55
- data/spec/generators/openehr/scaffold/scaffold_generator_spec.rb +0 -143
- data/spec/generators/templates/openEHR-EHR-CLUSTER.mml_name.v1.adl +0 -146
- data/spec/rcomponents/relement_spec.rb +0 -21
- data/spec/rcomponents/robservation_spec.rb +0 -21
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 8420a812bd6c4b3f95a403f4804fa58d660a1aa6d736d106bc0dc57a8b63e1ee
|
|
4
|
+
data.tar.gz: df4f5629f4915f03c4a07b944a168a1c53d08da043e07cbc6cf6d705d036f017
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0e39f211e2243b0ac74aff1408136652ba0b4f829a8bc28a92a842ba3e1636955d4ea9fcdfe6ee0e0351b9f3c7c5bd763139478574a5d5acf19c8f8fb9f62a5a
|
|
7
|
+
data.tar.gz: 4a8e6beb226a33825df8cd1d762b546cbaf4ca39877d2bda72ab8e81978a58fe57ceefa75ef1d372c609d495fb6d35adc65016592078d10f746be0f7ca041ed7
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1
|
|
2
|
+
#
|
|
3
|
+
# Dev container for openehr-rails gem development (not the demo app --
|
|
4
|
+
# see docker/demo.Dockerfile for that). Builds from the same Ruby base
|
|
5
|
+
# image as CI/demo for consistency.
|
|
6
|
+
|
|
7
|
+
ARG RUBY_VERSION=4.0.6
|
|
8
|
+
FROM docker.io/library/ruby:${RUBY_VERSION}-slim
|
|
9
|
+
|
|
10
|
+
RUN apt-get update -qq && \
|
|
11
|
+
apt-get install --no-install-recommends -y \
|
|
12
|
+
build-essential git libffi-dev libsqlite3-dev libyaml-dev pkg-config curl less vim-tiny && \
|
|
13
|
+
rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
|
|
14
|
+
|
|
15
|
+
RUN gem install bundler rails --no-document
|
|
16
|
+
|
|
17
|
+
WORKDIR /workspaces/openehr-rails
|
data/.dockerignore
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Keep .git -- openehr-rails.gemspec shells out to `git ls-files` at
|
|
2
|
+
# runtime (Bundler re-evaluates path gemspecs on every boot), so it must
|
|
3
|
+
# survive into the build context and the final image.
|
|
4
|
+
|
|
5
|
+
demo
|
|
6
|
+
coverage
|
|
7
|
+
pkg
|
|
8
|
+
log/*.log
|
|
9
|
+
tmp
|
|
10
|
+
.bundle
|
|
11
|
+
*.lock
|
|
12
|
+
.gem
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_call:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
spec:
|
|
11
|
+
name: spec (ruby ${{ matrix.ruby }}, rails ${{ matrix.rails }})
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
ruby: ['3.2', '3.3', '3.4', '4.0']
|
|
17
|
+
rails: ['7_2', '8_0', '8_1']
|
|
18
|
+
env:
|
|
19
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/rails_${{ matrix.rails }}.gemfile
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
- uses: ruby/setup-ruby@v1
|
|
23
|
+
with:
|
|
24
|
+
ruby-version: ${{ matrix.ruby }}
|
|
25
|
+
bundler-cache: true
|
|
26
|
+
- name: Run specs
|
|
27
|
+
run: bundle exec rake spec
|
|
28
|
+
|
|
29
|
+
demo-smoke:
|
|
30
|
+
name: demo smoke (openehr:scaffold end-to-end)
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
needs: spec
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
- uses: ruby/setup-ruby@v1
|
|
36
|
+
with:
|
|
37
|
+
ruby-version: '4.0'
|
|
38
|
+
bundler-cache: true
|
|
39
|
+
- name: Install rails CLI
|
|
40
|
+
run: gem install rails --no-document
|
|
41
|
+
- name: Build demo app from OPT templates
|
|
42
|
+
run: FORCE=1 bash script/build_demo.sh
|
|
43
|
+
- name: Run demo app's generated request specs
|
|
44
|
+
working-directory: demo
|
|
45
|
+
run: bundle exec rspec
|
|
46
|
+
|
|
47
|
+
template-smoke:
|
|
48
|
+
name: application template smoke test
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
needs: spec
|
|
51
|
+
steps:
|
|
52
|
+
- uses: actions/checkout@v4
|
|
53
|
+
- uses: ruby/setup-ruby@v1
|
|
54
|
+
with:
|
|
55
|
+
ruby-version: '4.0'
|
|
56
|
+
bundler-cache: true
|
|
57
|
+
- name: Install rails CLI
|
|
58
|
+
run: gem install rails --no-document
|
|
59
|
+
- name: Generate a new app from templates/openehr_template.rb
|
|
60
|
+
env:
|
|
61
|
+
OPENEHR_RAILS_PATH: ${{ github.workspace }}
|
|
62
|
+
OPENEHR_SAMPLES: '1'
|
|
63
|
+
run: |
|
|
64
|
+
rails new /tmp/openehr_template_smoke --database=sqlite3 --skip-test \
|
|
65
|
+
-m "$GITHUB_WORKSPACE/templates/openehr_template.rb"
|
|
66
|
+
- name: Run the generated app's request specs
|
|
67
|
+
working-directory: /tmp/openehr_template_smoke
|
|
68
|
+
run: bundle exec rspec
|
|
69
|
+
- name: Boot check
|
|
70
|
+
working-directory: /tmp/openehr_template_smoke
|
|
71
|
+
run: |
|
|
72
|
+
bin/rails runner '
|
|
73
|
+
raise "no templates registered" unless OpenehrTemplate.count == 3
|
|
74
|
+
puts "boot ok: #{OpenehrTemplate.count} templates registered"
|
|
75
|
+
'
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
ci:
|
|
13
|
+
uses: ./.github/workflows/ci.yml
|
|
14
|
+
|
|
15
|
+
release:
|
|
16
|
+
name: Release to RubyGems
|
|
17
|
+
needs: ci
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
permissions:
|
|
20
|
+
id-token: write # required for RubyGems Trusted Publishing (OIDC)
|
|
21
|
+
contents: read
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- uses: ruby/setup-ruby@v1
|
|
25
|
+
with:
|
|
26
|
+
ruby-version: '4.0'
|
|
27
|
+
bundler-cache: true
|
|
28
|
+
- name: release:check (clean tree, sibling-file tracking, gemspec validity)
|
|
29
|
+
run: bundle exec rake release:check
|
|
30
|
+
- name: Release
|
|
31
|
+
uses: rubygems/release-gem@v1
|
data/.gitignore
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/.bundle
|
|
2
2
|
|
|
3
|
-
/
|
|
4
|
-
/
|
|
3
|
+
# Generated demo Rails app (reproducible via script/build_demo.sh)
|
|
4
|
+
/demo
|
|
5
|
+
|
|
6
|
+
# /app and /config hold the admin engine (controllers, views, routes)
|
|
5
7
|
/public
|
|
6
8
|
/vendor
|
|
7
9
|
/plugin
|
|
@@ -26,6 +28,7 @@ pkg
|
|
|
26
28
|
#bundler
|
|
27
29
|
.bundle
|
|
28
30
|
*.lock
|
|
31
|
+
.gem
|
|
29
32
|
|
|
30
33
|
#
|
|
31
34
|
# For MacOS:
|
data/.rspec
CHANGED
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4.0.6
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.4.0] - 2026-08-13
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- `OpenehrRails.authenticate_with`: a pluggable authentication hook, run
|
|
12
|
+
as a `before_action` ahead of every engine action (admin UI, AQL
|
|
13
|
+
console, patient timeline, the `/v1` openEHR REST API, and the `/fhir`
|
|
14
|
+
facade). Host apps wire in their own mechanism (Devise, HTTP token,
|
|
15
|
+
anything) with the controller as context. Per-surface differentiation
|
|
16
|
+
via `openehr_access_scope` (`:admin`/`:rest_api`/`:fhir`).
|
|
17
|
+
- `OpenehrRails.allow_unauthenticated_access`: explicit opt-out for
|
|
18
|
+
intentionally-open deployments.
|
|
19
|
+
|
|
20
|
+
### Changed (behavior change -- read before upgrading)
|
|
21
|
+
- **The engine now denies all requests with `403 Forbidden` outside the
|
|
22
|
+
`development` and `test` environments unless `authenticate_with` or
|
|
23
|
+
`allow_unauthenticated_access` is configured.** Previously every
|
|
24
|
+
engine route (including the full openEHR REST API and the FHIR
|
|
25
|
+
facade's create endpoint) was open with no access control whatsoever.
|
|
26
|
+
Apps running 0.3.0 in production must configure one of the two before
|
|
27
|
+
upgrading, or the engine will start responding 403 to everything.
|
|
28
|
+
- `RemoteFetcher` now also rejects loopback/private/link-local (including
|
|
29
|
+
cloud metadata) addresses, both on the initial URL and on every
|
|
30
|
+
redirect hop, closing an SSRF gap (previously only the URL scheme was
|
|
31
|
+
validated).
|
|
32
|
+
- Every generic `rescue_from StandardError` handler across the engine's
|
|
33
|
+
controllers now logs the exception (class, message, and a short
|
|
34
|
+
backtrace) via `Rails.logger` before responding -- previously errors
|
|
35
|
+
were rendered to the client and left no server-side trace at all.
|
|
36
|
+
|
|
37
|
+
## [0.3.0] - 2026-08-13
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
- `rails g openehr:scaffold`/`openehr:fhir_profile` now accept an OPT URL in
|
|
41
|
+
place of a local path, via a new `OpenehrRails::Opt::RemoteFetcher`
|
|
42
|
+
(redirect-following, timeout- and size-bounded HTTP(S) fetch that
|
|
43
|
+
validates the response actually parses as an operational template).
|
|
44
|
+
- Admin UI (`/openehr`) gained a URL-import field (`OpenehrRails::TemplateImporter`),
|
|
45
|
+
the URL counterpart to the existing drag & drop upload.
|
|
46
|
+
- AQL query support: `OpenehrRails::Aql` (dataset adapter, query validator,
|
|
47
|
+
executor) and a `Model.aql(query, params:)` scope on every scaffolded
|
|
48
|
+
model, plus a browser AQL console at `/openehr/query`.
|
|
49
|
+
- openEHR REST API surface at `/openehr/v1`: `EHR`, `EHR_STATUS`,
|
|
50
|
+
`COMPOSITION` (create/read/update/delete with optimistic concurrency),
|
|
51
|
+
and `QUERY` (AQL).
|
|
52
|
+
- Patient timeline UI at `/openehr/ehrs` (per-EHR composition history,
|
|
53
|
+
grouped by date, with version history disclosure).
|
|
54
|
+
- Docker: `docker/demo.Dockerfile` + `docker/docker-compose.yml` run the
|
|
55
|
+
full demo app in a container with no local Ruby/Rails install needed;
|
|
56
|
+
`.devcontainer/` for gem development itself.
|
|
57
|
+
- `templates/openehr_template.rb`: a Rails application template
|
|
58
|
+
(`rails new myehr -m <url>`) that wires up a brand new app with
|
|
59
|
+
openehr-rails end to end, optionally scaffolding the same 3 sample
|
|
60
|
+
templates as the demo. `script/build_starter.sh` wraps it into a
|
|
61
|
+
standalone repo (README + CI) suitable for a GitHub template repository.
|
|
62
|
+
- CI matrix expanded to Ruby 3.2/3.3/3.4/4.0 x Rails 7.2/8.0/8.1
|
|
63
|
+
(`gemfiles/rails_{7_2,8_0,8_1}.gemfile`), plus a demo-smoke job that
|
|
64
|
+
builds the demo app and runs its generated request specs end to end.
|
|
65
|
+
- `LICENSE` file (Apache License 2.0, matching the gemspec's declared
|
|
66
|
+
license -- previously declared but not actually included in the repo).
|
|
67
|
+
|
|
68
|
+
### Changed
|
|
69
|
+
- Upgraded the `openehr` runtime dependency from `~> 1.3.0` to `~> 2.0`
|
|
70
|
+
(currently resolves to 2.0.2).
|
|
71
|
+
- `gem.license` corrected to the valid SPDX identifier `Apache-2.0`
|
|
72
|
+
(was the non-SPDX string `"Apache 2.0"`).
|
|
73
|
+
- Added `gem.metadata` (`source_code_uri`, `changelog_uri`,
|
|
74
|
+
`bug_tracker_uri`, `rubygems_mfa_required`) and dropped the deprecated
|
|
75
|
+
`gem.test_files` assignment.
|
|
76
|
+
|
|
77
|
+
### Fixed
|
|
78
|
+
- `OpenehrRails::Rm` was never `require`d by `lib/openehr_rails.rb`,
|
|
79
|
+
silently disabling the entire RM persistence layer (typed node graph,
|
|
80
|
+
AQL, versioning) in any real host application -- it only appeared to
|
|
81
|
+
work in this gem's own test suite because the spec support file
|
|
82
|
+
required it separately. This was the most significant bug found during
|
|
83
|
+
the 2.0 upgrade work.
|
|
84
|
+
- `OpenehrRails::Opt::Parser`'s raw-content-vs-path detection didn't
|
|
85
|
+
account for a leading UTF-8 BOM, so any BOM-prefixed OPT (common in
|
|
86
|
+
real-world exports) misdetected as a file path and crashed. Affected
|
|
87
|
+
every raw-content caller (`TemplateUploader`, `TemplateRegistry`,
|
|
88
|
+
`Fhir::ProfileRepository`, `RemoteFetcher`), not just one code path.
|
|
89
|
+
- `RmObjectBuilder#build_composition` never set `uid:`, so
|
|
90
|
+
`SELECT c/uid/value` always returned nil.
|
|
91
|
+
- `EventContext#setting` used a raw `CODE_PHRASE` where openehr 2.0
|
|
92
|
+
requires a `DV_CODED_TEXT`.
|
|
93
|
+
|
|
94
|
+
### Removed
|
|
95
|
+
- Legacy ADL-archetype-only generators (`model`/`controller`/`migration`/
|
|
96
|
+
`helper`/`assets`/`i18n`/`template`/`template_model`, and their shared
|
|
97
|
+
`Openehr::Generators::ArchetypedBase`). OPT is now the only supported
|
|
98
|
+
scaffolding input format; `OpenehrTemplate.from_adl_file` (ADL
|
|
99
|
+
*registration*, not scaffolding) is unaffected.
|
|
100
|
+
- The `ckm_client` gem dependency (only used by the removed legacy
|
|
101
|
+
generators).
|
|
102
|
+
|
|
103
|
+
## [0.2.2] and earlier
|
|
104
|
+
|
|
105
|
+
Predates this changelog. See `git log` for history back to the project's
|
|
106
|
+
first commit in 2012.
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Principle
|
|
6
|
+
|
|
7
|
+
Follow the TDD framework as advocated by t-wada:
|
|
8
|
+
- 🔴 Red: Write a failing test
|
|
9
|
+
- 🟢 Green: Write the minimal implementation to pass the test
|
|
10
|
+
- 🔵 Refactor: Improve the code while keeping tests green
|
|
11
|
+
- Take small steps
|
|
12
|
+
- Start with fake implementation (hard-coded values)
|
|
13
|
+
- Use triangulation to generalize
|
|
14
|
+
- Direct implementation is OK when the solution is obvious
|
|
15
|
+
- Keep the test list constantly updated
|
|
16
|
+
- Write tests for areas of concern first
|
|
17
|
+
- opt files must not be changed automatically.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## Project Overview
|
|
21
|
+
|
|
22
|
+
This is `openehr-rails`, a Rails engine gem that turns an openEHR Operational Template (`.opt`, ADL2/XML) into a working Rails resource in one command: `rails generate openehr:scaffold path/to/template.opt --fhir` emits a model, migration, controller, views, i18n locale, and (with `--fhir`) HL7 FHIR R5 `StructureDefinition` profiles. Generated models persist both as typed columns (for forms/search) and as full openEHR RM data (canonical JSON + a typed node graph with immutable-append versioning), and are queryable via a growing AQL surface. A mountable admin engine (`/openehr`) provides template upload/management, runtime scaffolding, and a FHIR R5 facade. Legacy ADL-archetype-only generators (model/controller/migration/helper/assets/i18n/template/template_model, based on `Openehr::Generators::ArchetypedBase`) have been removed — OPT is the only supported input format for scaffolding.
|
|
23
|
+
|
|
24
|
+
## Key Commands
|
|
25
|
+
|
|
26
|
+
**Testing:**
|
|
27
|
+
- `rake spec` - Run all RSpec tests
|
|
28
|
+
- `rake` - Default task runs specs
|
|
29
|
+
- `bundle exec rspec spec/path/to/specific_spec.rb` - Run specific test file
|
|
30
|
+
|
|
31
|
+
**Development:**
|
|
32
|
+
- `bundle install` - Install dependencies
|
|
33
|
+
- `bundle exec rake` - Run tests via bundler
|
|
34
|
+
- `bundle exec guard` - Run Guard for automated testing (requires guard-rspec)
|
|
35
|
+
|
|
36
|
+
**Gem Development:**
|
|
37
|
+
- `rake build` - Build the gem (via bundler/gem_tasks)
|
|
38
|
+
- `rake install` - Install the gem locally
|
|
39
|
+
- `rake release` - Release the gem
|
|
40
|
+
|
|
41
|
+
**Demo app** (reproducible, git-ignored): `bash script/build_demo.sh` builds a Rails 8 app in `demo/` from the OPTs and seed data in `demo_assets/`, scaffolding three templates (BMI, problem list, blood pressure) with FHIR profiles. See `doc/DEMO_ja.md` for the full walkthrough.
|
|
42
|
+
|
|
43
|
+
## Architecture & Structure
|
|
44
|
+
|
|
45
|
+
### Generators (`lib/generators/openehr/`)
|
|
46
|
+
|
|
47
|
+
- `install/` - one-time setup: mounts the engine at `/openehr`, creates the `OpenehrTemplate` registry model and the `openehr_ehrs` / `openehr_rm_*` RM persistence tables.
|
|
48
|
+
- `scaffold/` - the core generator. Takes an `.opt` file (or, per the roadmap, a remote URL), parses it via `OpenehrRails::Opt::Parser`, extracts fields via `OpenehrRails::Opt::FieldExtractor`, and emits model/migration/controller/views/locale/request-spec/routes. `--namespace` and `--fhir` options available.
|
|
49
|
+
- `fhir_profile/` - emits FHIR R5 `StructureDefinition` JSON per OPT entry into `app/fhir/profiles/`.
|
|
50
|
+
|
|
51
|
+
### Runtime library (`lib/openehr_rails/`)
|
|
52
|
+
|
|
53
|
+
- `opt.rb`, `opt/parser.rb`, `opt/field_extractor.rb` - OPT parsing (subclasses `OpenEHR::Parser::OPTParser` from the `openehr` gem) and flattening of ENTRY/ELEMENT constraints into field hashes (`FIELD_MAP` is the single source of truth tying a generated column to an RM path + data type).
|
|
54
|
+
- `storable.rb` - mixed into scaffolded models (`OpenehrRails::Storable`): on save, builds a canonical openEHR RM Composition from `FIELD_MAP`, caches it as JSON (`rm_composition` column), and persists it into the RM graph.
|
|
55
|
+
- `rm/` - the RM persistence layer: `Composition`/`Node`/`DataValue` (STI, `openehr_rm_*` tables), `GraphBuilder` (canonical JSON → graph rows), `CanonicalSerializer` (graph → canonical JSON, round-trip invariant), `GraphPersister` (immutable-append versioning), `RmObjectBuilder` (graph → real `OpenEHR::RM` objects), `Ehr`/`Contribution`/`Version` (audit trail).
|
|
56
|
+
- `aql_queryable.rb` - `Model.find_by_path` (FIELD_MAP lookup with RM-graph fallback); full AQL query support is planned to build on the same path-to-column resolution (see roadmap in the project's plan history).
|
|
57
|
+
- `template_registry.rb`, `template_uploader.rb`, `runtime_scaffolder.rb` - the `OpenehrTemplate` model (supports both OPT and legacy ADL archetype registration) and the admin engine's upload + in-process `openehr:scaffold` invocation.
|
|
58
|
+
- `fhir/` - FHIR R5 facade: profile generation, canonical-RM ⇄ FHIR serialization, resource registry, capability statement, served at `/openehr/fhir` by `app/controllers/openehr_rails/fhir_controller.rb`.
|
|
59
|
+
|
|
60
|
+
### Testing Structure
|
|
61
|
+
|
|
62
|
+
- RSpec with `ammeter` for generator specs; in-memory SQLite (`spec/support/active_record.rb`) for RM-layer specs.
|
|
63
|
+
- `spec/generators/openehr/{install,scaffold,fhir_profile}/` - generator specs (only these three generators remain).
|
|
64
|
+
- `spec/openehr_rails/{opt,rm,fhir}/`, `spec/openehr_rails/*_spec.rb` - runtime library specs.
|
|
65
|
+
- `spec/models/openehr_template_spec.rb`, `spec/unit/opt_parser_spec.rb` - registry model and parser specs.
|
|
66
|
+
- OPT fixtures live in `spec/generators/templates/` and `spec/templates/`; do not hand-edit an existing `.opt` fixture (add a new one instead) — **opt files must not be changed automatically.**
|
|
67
|
+
|
|
68
|
+
## Development Notes
|
|
69
|
+
|
|
70
|
+
- Ruby 3.0+ required; CI matrix covers 3.2/3.3/3.4/4.0, local dev pinned via `.ruby-version` (currently 4.0.6)
|
|
71
|
+
- Rails 7.0+ and Rails 8.x supported (CI matrix: `gemfiles/rails_{7_2,8_0,8_1}.gemfile`; demo app runs on Rails 8.1)
|
|
72
|
+
- URI compatibility workaround implemented for Ruby 3.4
|
|
73
|
+
- `ostruct` is an explicit development dependency — it left Ruby's default gems as of 4.0, and a couple of specs use `OpenStruct` as a lightweight test double
|
|
74
|
+
- Guard setup available for TDD workflow
|
|
75
|
+
- RuboCop Rails linting configured
|
|
76
|
+
- SimpleCov for test coverage
|
|
77
|
+
- `openehr` gem dependency; see the gem's own README/CHANGELOG for OPT-parser and AQL-engine capabilities and known gaps before relying on either.
|
data/Guardfile
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# A sample Guardfile
|
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
|
3
|
+
|
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
|
5
|
+
# directories %w(app lib config test spec features) \
|
|
6
|
+
# .select{|d| Dir.exist?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
|
7
|
+
|
|
8
|
+
## Note: if you are using the `directories` clause above and you are not
|
|
9
|
+
## watching the project directory ('.'), then you will want to move
|
|
10
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
|
11
|
+
#
|
|
12
|
+
# $ mkdir config
|
|
13
|
+
# $ mv Guardfile config/
|
|
14
|
+
# $ ln -s config/Guardfile .
|
|
15
|
+
#
|
|
16
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
|
17
|
+
|
|
18
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
|
19
|
+
# rspec may be run, below are examples of the most common uses.
|
|
20
|
+
# * bundler: 'bundle exec rspec'
|
|
21
|
+
# * bundler binstubs: 'bin/rspec'
|
|
22
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
|
23
|
+
# installed the spring binstubs per the docs)
|
|
24
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
|
25
|
+
# * 'just' rspec: 'rspec'
|
|
26
|
+
|
|
27
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
|
28
|
+
require "guard/rspec/dsl"
|
|
29
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
|
30
|
+
|
|
31
|
+
# Feel free to open issues for suggestions and improvements
|
|
32
|
+
|
|
33
|
+
# RSpec files
|
|
34
|
+
rspec = dsl.rspec
|
|
35
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
|
36
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
|
37
|
+
watch(rspec.spec_files)
|
|
38
|
+
|
|
39
|
+
# Ruby files
|
|
40
|
+
ruby = dsl.ruby
|
|
41
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
|
42
|
+
|
|
43
|
+
# # Rails files
|
|
44
|
+
# rails = dsl.rails(view_extensions: %w(erb haml slim))
|
|
45
|
+
# dsl.watch_spec_files_for(rails.app_files)
|
|
46
|
+
# dsl.watch_spec_files_for(rails.views)
|
|
47
|
+
|
|
48
|
+
# watch(rails.controllers) do |m|
|
|
49
|
+
# [
|
|
50
|
+
# rspec.spec.call("routing/#{m[1]}_routing"),
|
|
51
|
+
# rspec.spec.call("controllers/#{m[1]}_controller"),
|
|
52
|
+
# rspec.spec.call("acceptance/#{m[1]}")
|
|
53
|
+
# ]
|
|
54
|
+
# end
|
|
55
|
+
|
|
56
|
+
# # Rails config changes
|
|
57
|
+
# watch(rails.spec_helper) { rspec.spec_dir }
|
|
58
|
+
# watch(rails.routes) { "#{rspec.spec_dir}/routing" }
|
|
59
|
+
# watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
|
|
60
|
+
|
|
61
|
+
# # Capybara features specs
|
|
62
|
+
# watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
|
|
63
|
+
# watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
|
|
64
|
+
|
|
65
|
+
# # Turnip features and steps
|
|
66
|
+
# watch(%r{^spec/acceptance/(.+)\.feature$})
|
|
67
|
+
# watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
|
68
|
+
# Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
|
|
69
|
+
# end
|
|
70
|
+
end
|
data/LICENSE
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
Copyright 2012-2026 Shinji KOBAYASHI
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
Apache License
|
|
17
|
+
Version 2.0, January 2004
|
|
18
|
+
http://www.apache.org/licenses/
|
|
19
|
+
|
|
20
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
21
|
+
|
|
22
|
+
1. Definitions.
|
|
23
|
+
|
|
24
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
25
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
26
|
+
|
|
27
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
28
|
+
the copyright owner that is granting the License.
|
|
29
|
+
|
|
30
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
31
|
+
other entities that control, are controlled by, or are under common
|
|
32
|
+
control with that entity. For the purposes of this definition,
|
|
33
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
34
|
+
direction or management of such entity, whether by contract or
|
|
35
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
36
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
37
|
+
|
|
38
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
39
|
+
exercising permissions granted by this License.
|
|
40
|
+
|
|
41
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
42
|
+
including but not limited to software source code, documentation
|
|
43
|
+
source, and configuration files.
|
|
44
|
+
|
|
45
|
+
"Object" form shall mean any form resulting from mechanical
|
|
46
|
+
transformation or translation of a Source form, including but
|
|
47
|
+
not limited to compiled object code, generated documentation,
|
|
48
|
+
and conversions to other media types.
|
|
49
|
+
|
|
50
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
51
|
+
Object form, made available under the License, as indicated by a
|
|
52
|
+
copyright notice that is included in or attached to the work
|
|
53
|
+
(an example is provided in the Appendix below).
|
|
54
|
+
|
|
55
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
56
|
+
form, that is based on (or derived from) the Work and for which the
|
|
57
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
58
|
+
represent, as a whole, an original work of authorship. For the
|
|
59
|
+
purposes of this License, Derivative Works shall not include works
|
|
60
|
+
that remain separable from, or merely link (or bind by name) to the
|
|
61
|
+
interfaces of, the Work and Derivative Works thereof.
|
|
62
|
+
|
|
63
|
+
"Contribution" shall mean any work of authorship, including the
|
|
64
|
+
original version of the Work and any modifications or additions to
|
|
65
|
+
that Work or Derivative Works thereof, that is intentionally submitted
|
|
66
|
+
to Licensor for inclusion in the Work by the copyright owner or by an
|
|
67
|
+
individual or Legal Entity authorized to submit on behalf of the
|
|
68
|
+
copyright owner. For the purposes of this definition, "submitted"
|
|
69
|
+
means any form of electronic, verbal, or written communication sent
|
|
70
|
+
to the Licensor or its representatives, including but not limited to
|
|
71
|
+
communication on electronic mailing lists, source code control
|
|
72
|
+
systems, and issue tracking systems that are managed by, or on behalf
|
|
73
|
+
of, the Licensor for the purpose of discussing and improving the
|
|
74
|
+
Work, but excluding communication that is conspicuously marked or
|
|
75
|
+
otherwise designated in writing by the copyright owner as
|
|
76
|
+
"Not a Contribution."
|
|
77
|
+
|
|
78
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
79
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
80
|
+
subsequently incorporated within the Work.
|
|
81
|
+
|
|
82
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
83
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
84
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
85
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
86
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
87
|
+
Work and such Derivative Works in Source or Object form.
|
|
88
|
+
|
|
89
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
90
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
91
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
92
|
+
(except as stated in this section) patent license to make, have
|
|
93
|
+
made, use, offer to sell, sell, import, and otherwise transfer the
|
|
94
|
+
Work, where such license applies only to those patent claims
|
|
95
|
+
licensable by such Contributor that are necessarily infringed by
|
|
96
|
+
their Contribution(s) alone or by combination of their
|
|
97
|
+
Contribution(s) with the Work to which such Contribution(s) was
|
|
98
|
+
submitted. If You institute patent litigation against any entity
|
|
99
|
+
(including a cross-claim or counterclaim in a lawsuit) alleging
|
|
100
|
+
that the Work or a Contribution incorporated within the Work
|
|
101
|
+
constitutes direct or contributory patent infringement, then any
|
|
102
|
+
patent licenses granted to You under this License for that Work
|
|
103
|
+
shall terminate as of the date such litigation is filed.
|
|
104
|
+
|
|
105
|
+
4. Redistribution. You may reproduce and distribute copies of the Work
|
|
106
|
+
or Derivative Works thereof in any medium, with or without
|
|
107
|
+
modifications, and in Source or Object form, provided that You
|
|
108
|
+
meet the following conditions:
|
|
109
|
+
|
|
110
|
+
(a) You must give any other recipients of the Work or Derivative
|
|
111
|
+
Works a copy of this License; and
|
|
112
|
+
|
|
113
|
+
(b) You must cause any modified files to carry prominent notices
|
|
114
|
+
stating that You changed the files; and
|
|
115
|
+
|
|
116
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
117
|
+
that You distribute, all copyright, patent, trademark, and
|
|
118
|
+
attribution notices from the Source form of the Work,
|
|
119
|
+
excluding those notices that do not pertain to any part of
|
|
120
|
+
the Derivative Works; and
|
|
121
|
+
|
|
122
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
123
|
+
distribution, then any Derivative Works that You distribute must
|
|
124
|
+
include a readable copy of the attribution notices contained
|
|
125
|
+
within such NOTICE file, excluding those notices that do not
|
|
126
|
+
pertain to any part of the Derivative Works, in at least one
|
|
127
|
+
of the following places: within a NOTICE text file distributed
|
|
128
|
+
as part of the Derivative Works; within the Source form or
|
|
129
|
+
documentation, if provided along with the Derivative Works; or,
|
|
130
|
+
within a display generated by the Derivative Works, if and
|
|
131
|
+
wherever such third-party notices normally appear. The contents
|
|
132
|
+
of the NOTICE file are for informational purposes only and do
|
|
133
|
+
not modify the License. You may add Your own attribution
|
|
134
|
+
notices within Derivative Works that You distribute, alongside
|
|
135
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
136
|
+
that such additional attribution notices cannot be construed
|
|
137
|
+
as modifying the License.
|
|
138
|
+
|
|
139
|
+
You may add Your own copyright statement to Your modifications and
|
|
140
|
+
may provide additional or different license terms and conditions
|
|
141
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
142
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
143
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
144
|
+
the conditions stated in this License.
|
|
145
|
+
|
|
146
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
147
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
148
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
149
|
+
this License, without any additional terms or conditions.
|
|
150
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
151
|
+
the terms of any separate license agreement you may have executed
|
|
152
|
+
with Licensor regarding such Contributions.
|
|
153
|
+
|
|
154
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
155
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
156
|
+
except as required for reasonable and customary use in describing
|
|
157
|
+
the origin of the Work and reproducing the content of the NOTICE
|
|
158
|
+
file.
|
|
159
|
+
|
|
160
|
+
7. Disclaimer of Warranty. Unless required by applicable law or agreed
|
|
161
|
+
to in writing, Licensor provides the Work (and each Contributor
|
|
162
|
+
provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES
|
|
163
|
+
OR CONDITIONS OF ANY KIND, either express or implied, including,
|
|
164
|
+
without limitation, any warranties or conditions of TITLE,
|
|
165
|
+
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR
|
|
166
|
+
PURPOSE. You are solely responsible for determining the
|
|
167
|
+
appropriateness of using or redistributing the Work and assume any
|
|
168
|
+
risks associated with Your exercise of permissions under this
|
|
169
|
+
License.
|
|
170
|
+
|
|
171
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
172
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
173
|
+
unless required by applicable law (such as deliberate and grossly
|
|
174
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
175
|
+
liable to You for damages, including any direct, indirect, special,
|
|
176
|
+
incidental, or consequential damages of any character arising as a
|
|
177
|
+
result of this License or out of the use or inability to use the
|
|
178
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
179
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
180
|
+
other commercial damages or losses), even if such Contributor has
|
|
181
|
+
been advised of the possibility of such damages.
|
|
182
|
+
|
|
183
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
184
|
+
the Work or Derivative Works thereof, You may choose to offer, and
|
|
185
|
+
charge a fee for, acceptance of support, warranty, indemnity, or
|
|
186
|
+
other liability obligations and/or rights consistent with this
|
|
187
|
+
License. However, in accepting such obligations, You may act only
|
|
188
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
189
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
190
|
+
defend, and hold each Contributor harmless for any liability
|
|
191
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
192
|
+
of your accepting any such warranty or additional liability.
|
|
193
|
+
|
|
194
|
+
END OF TERMS AND CONDITIONS
|