diff --git a/production_tests.sh b/production_tests.sh
index 299c9328ee510c1e5d4b2b78b114a6a9197e876f..24abf25e9f3e3427db6019e07465a033dfd8f59f 100755
--- a/production_tests.sh
+++ b/production_tests.sh
@@ -26,9 +26,9 @@ curl http://127.0.0.1:8000/stationmeta/
 curl http://127.0.0.1:8000/stationmeta_core/DEUB001
 curl http://127.0.0.1:8000/stationmeta/DEUB001
 # station upload without nested fields
-curl -X POST -H "Content-Type:application/json" -d '{"stationmeta": {"codes":["China11"],"name":"Mount Tai","coordinates":{"lat":36.256,"lng":17.106,"alt":1534.0},"country":"China","state":"Shandong Sheng","coordinate_validation_status":"NotChecked","coordinate_validation_date":"2020-03-11T12:22:18.047974+01:00","type_of_environment":"Background","type_of_area":"Rural","category":"","timezone":"Asia/Shanghai", "coordinate_validator_id": 1, "additional_metadata":"{}"}}' "http://127.0.0.1:8000/stationmeta/"
+curl -X POST -H "Content-Type:application/json" -d '{"stationmeta": {"codes":["China11"],"name":"Mount Tai","coordinates":{"lat":36.256,"lng":17.106,"alt":1534.0},"country":"China","state":"Shandong Sheng","type_of_environment":"Background","type_of_area":"Rural","category":"","timezone":"Asia/Shanghai","additional_metadata":"{}"}}' "http://127.0.0.1:8000/stationmeta/"
 # (nested) upload including 'global' (not defining all metadata -- getting the rest from default values) with human readable fields
-curl -X POST -H "Content-Type:application/json" -d '{"stationmeta": {"codes":["CHHKG015"],"name":"Shatin","coordinates":{"lat":22.3765,"lng":114.1847,"alt":25},"country":"China","state":"New Territories","coordinate_validation_status":"NotChecked","coordinate_validation_date":"2020-03-11T12:22:18.047974+01:00","type_of_environment":"Unknown","type_of_area":"Suburban","category":"","timezone":"Asia/Hong_Kong", "coordinate_validator_id": 1, "additional_metadata":"{}", "roles": [{"role": "PointOfContact", "contact_id": 43, "status": "active"},{"role": "PrincipalInvestigator", "contact_id": 41, "status": "active"}], "globalmeta": {"climatic_zone": "WarmTemperateMoist"}}}' http://127.0.0.1:8000/stationmeta/ 
+curl -X POST -H "Content-Type:application/json" -d '{"stationmeta": {"codes":["CHHKG015"],"name":"Shatin","coordinates":{"lat":22.3765,"lng":114.1847,"alt":25},"country":"China","state":"New Territories","type_of_environment":"Unknown","type_of_area":"Suburban","category":"","timezone":"Asia/Hong_Kong","additional_metadata":"{}", "roles": [{"role": "PointOfContact", "contact_id": 43, "status": "active"},{"role": "PrincipalInvestigator", "contact_id": 41, "status": "active"}], "globalmeta": {"climatic_zone": "WarmTemperateMoist"}}}' http://127.0.0.1:8000/stationmeta/ 
 
 curl http://127.0.0.1:8000/timeseries/
 curl http://127.0.0.1:8000/timeseries/97
diff --git a/toardb/generic/models.py b/toardb/generic/models.py
index 42beb57373cfb496042303a71344b37a9733c629..ad6af6b31157305fc1981556dba295a99663ef66 100644
--- a/toardb/generic/models.py
+++ b/toardb/generic/models.py
@@ -38,3 +38,23 @@ RC_enum = (
     Enumdict(5, 'ResourceProvider', 'resource provider')
     )
 
+# Changelog: Type of Change
+CL_enum_table = Table("cl_vocabulary",
+                      Base.metadata,
+                      Column("enum_val", Integer, primary_key=True),
+                      Column("enum_str", String),
+                      Column("enum_display_str", String)
+                      )
+# The following code is just a workaround (see stationmeta/models.py):
+from collections import namedtuple
+Enumdict=namedtuple("Dict",["value","string","display_str"])
+CL_enum = (
+    Enumdict(0, 'Created', 'created'),
+    Enumdict(1, 'SingleValue', 'single value correction in metadata'),
+    Enumdict(2, 'Comprehensive', 'comprehensive metadata revision'),
+    Enumdict(3, 'Typo', 'typographic correction of metadata'),
+    Enumdict(4, 'UnspecifiedData', 'unspecified data value corrections'),
+    Enumdict(5, 'Replaced', 'replaced data with a new version'),
+    Enumdict(6, 'Flagging', 'data value flagging')
+    )
+
diff --git a/toardb/stationmeta/models.py b/toardb/stationmeta/models.py
index a0b8409923a1d3341c457f1671be8fb6b9762800..bceee936402944a0d5a921c8cd8c33460524516c 100644
--- a/toardb/stationmeta/models.py
+++ b/toardb/stationmeta/models.py
@@ -6,6 +6,7 @@ from .models_global_services import StationmetaGlobalService
 from .models_role import StationmetaRole, stationmeta_core_stationmeta_roles_table
 from .models_annotation import StationmetaAnnotation, stationmeta_core_stationmeta_annotations_table
 from .models_aux import StationmetaAuxDoc, StationmetaAuxImage, StationmetaAuxUrl
+from .models_changelog import StationmetaChangelog
 
 from toardb.base import Base
 
diff --git a/toardb/stationmeta/models_changelog.py b/toardb/stationmeta/models_changelog.py
new file mode 100644
index 0000000000000000000000000000000000000000..329837057995fda916bcb11f3921d4924344ba73
--- /dev/null
+++ b/toardb/stationmeta/models_changelog.py
@@ -0,0 +1,61 @@
+# coding: utf-8
+"""
+class StationmetaChangelog(Base)
+================================
+"""
+from sqlalchemy import Column, DateTime, BigInteger, ForeignKey, String, \
+                       Text, CheckConstraint, Table, Sequence
+from sqlalchemy.orm import relationship
+from .models_core import StationmetaCore
+from toardb.auth_user.models import AuthUser
+from toardb.base import Base
+
+STATIONMETA_CHANGELOG_ID_SEQ = Sequence('stationmeta_changelog_id_seq')  # define sequence explicitly
+class StationmetaChangelog(Base):
+    """ Table "public.stationmeta_changelog"
+
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------------+
+    |     Column     |           Type           | Collation | Nullable |                      Default                           |
+    +================+==========================+===========+==========+========================================================+
+    | id             | bigint                   |           | not null | nextval('stationmeta_changelog_id_seq'::regclass)      |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------------+
+    | datetime       | timestamp with time zone |           | not null |                                                        |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------------+
+    | station_id     | bigint                   |           | not null |                                                        |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------------+
+    | type_of_change | integer                  |           | not null |                                                        |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------------+
+    | description    | text                     |           | not null |                                                        |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------------+
+    | old_value      | character varying(256)   |           | not null |                                                        |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------------+
+    | new_value      | character varying(256)   |           | not null |                                                        |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------------+
+    | author_id      | integer                  |           | not null |                                                        |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------------+
+    Indexes:
+     "stationmeta_changelog_pkey" PRIMARY KEY, btree (id)
+    Foreign-key constraints:
+     "stationmeta_changelog_author_id_fk_auth_user_id" FOREIGN KEY (author_id) REFERENCES auth_user(id)
+     "stationmeta_changelog_station_id_fk_stationmeta_core_id" FOREIGN KEY (station_id) REFERENCES stationmeta_core(id)
+     "stationmeta_changelog_type_of_change_fk_cl_vocabulary_enum_val" FOREIGN KEY (type_of_change) REFERENCES cl_vocabulary(enum_val)
+    """
+    __tablename__ = 'stationmeta_changelog'
+
+    id = Column(BigInteger, STATIONMETA_CHANGELOG_ID_SEQ, primary_key=True, server_default=STATIONMETA_CHANGELOG_ID_SEQ.next_value())
+    datetime = Column(DateTime(True), nullable=False)
+    description = Column(Text, nullable=False)
+    old_value = Column(String(256), nullable=False)
+    new_value = Column(String(256), nullable=False)
+# do not use string declaration here (not working for pytest)
+# use the explicit class name here,
+# see: https://groups.google.com/forum/#!topic/sqlalchemy/YjGhE4d6K4U
+    station_id = Column(ForeignKey(StationmetaCore.id), nullable=False)
+    author_id = Column(ForeignKey(AuthUser.id), nullable=False)
+# still to check for some pytest solution for controlled vocabulary
+    type_of_change = Column(ForeignKey('cl_Vocabulary.enum_val'), nullable=False)
+
+    author = relationship('AuthUser')
+    station = relationship('StationmetaCore')
+
+#   cl_vocabulary = relationship('ClVocabulary')
diff --git a/toardb/stationmeta/models_core.py b/toardb/stationmeta/models_core.py
index 1f0b0eaa2ade3198b4b3e34eb4fb754cc38783dd..7e263307fa7112cabdefec76dcc2b2254508880a 100644
--- a/toardb/stationmeta/models_core.py
+++ b/toardb/stationmeta/models_core.py
@@ -35,10 +35,6 @@ class StationmetaCore_WithoutCoords(Base):
     +------------------------------+--------------------------+-----------+----------+----------------------------------------------+
     | state                        | character varying(128)   |           | not null |                                              |
     +------------------------------+--------------------------+-----------+----------+----------------------------------------------+
-    | coordinate_validation_status | integer                  |           | not null |                                              |
-    +------------------------------+--------------------------+-----------+----------+----------------------------------------------+
-    | coordinate_validation_date   | timestamp with time zone |           | not null |                                              |
-    +------------------------------+--------------------------+-----------+----------+----------------------------------------------+
     | type_of_environment          | integer                  |           | not null |                                              |
     +------------------------------+--------------------------+-----------+----------+----------------------------------------------+
     | type_of_area                 | integer                  |           | not null |                                              |
@@ -47,23 +43,17 @@ class StationmetaCore_WithoutCoords(Base):
     +------------------------------+--------------------------+-----------+----------+----------------------------------------------+
     | additional_metadata          | jsonb                    |           | not null |                                              |
     +------------------------------+--------------------------+-----------+----------+----------------------------------------------+
-    | coordinate_validator_id      | integer                  |           | not null |                                              |
-    +------------------------------+--------------------------+-----------+----------+----------------------------------------------+
     Indexes:
         "stationmeta_core_pkey" PRIMARY KEY, btree (id)
-        "stationmeta_core_coordinate_validator_id_38c0ef8d" btree (coordinate_validator_id)
         "stationmeta_core_coordinates_id" gist (coordinates gist_geometry_ops_nd)
         "stationmeta_core_country_fa755dde" btree (country)
         "stationmeta_core_country_fa755dde_like" btree (country varchar_pattern_ops)
         "stationmeta_core_state_85025a96" btree (state)
         "stationmeta_core_state_85025a96_like" btree (state varchar_pattern_ops)
     Check constraints:
-        "stationmeta_core_coordinate_validation_status_check" CHECK (coordinate_validation_status >= 0)
         "stationmeta_core_type_of_area_check" CHECK (type_of_area >= 0)
         "stationmeta_core_type_of_environment_check" CHECK (type_of_environment >= 0)
     Foreign-key constraints:
-        "stationmeta_core_coordinate_validator_38c0ef8d_fk_auth_user" FOREIGN KEY (coordinate_validator_id) REFERENCES auth_user(id) DEFERRABLE INITIALLY DEFERRED
-        "stationmeta_core_coord_valid_status_fk_cv_vocabulary_enum_val" FOREIGN KEY (coordinate_validation_status) REFERENCES cv_vocabulary(enum_val)
         "stationmeta_core_type_of_area_fk_ta_vocabulary_enum_val" FOREIGN KEY (type_of_area) REFERENCES ta_vocabulary(enum_val)
         "stationmeta_core_type_of_environment_fk_st_vocabulary_enum_val" FOREIGN KEY (type_of_environment) REFERENCES st_vocabulary(enum_val)
     Referenced by:
@@ -78,7 +68,6 @@ class StationmetaCore_WithoutCoords(Base):
 
     __tablename__ = 'stationmeta_core'
     __table_args__ = (
-                        CheckConstraint('coordinate_validation_status >= 0'),
                         CheckConstraint('type_of_area >= 0'),
                         CheckConstraint('type_of_environment >= 0')
                      )
@@ -88,15 +77,10 @@ class StationmetaCore_WithoutCoords(Base):
     name = Column(String(128), nullable=False)
     country = Column(String(128), nullable=False, index=True)
     state = Column(String(128), nullable=False, index=True)
-    coordinate_validation_status = Column(ForeignKey('cv_vocabulary.enum_val'), nullable=False)
-    coordinate_validation_date = Column(DateTime(True), nullable=False)
     type_of_environment = Column(ForeignKey('st_vocabulary.enum_val'), nullable=False)
     type_of_area = Column(ForeignKey('ta_vocabulary.enum_val'), nullable=False)
     timezone = Column(String(64), nullable=False)
     additional_metadata = Column(JSONB(astext_type=Text()), nullable=True)
-    coordinate_validator_id = Column(ForeignKey(AuthUser.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True)
-
-    coordinate_validator = relationship('AuthUser')
 
     aux_images = relationship('StationmetaAuxImage', back_populates='station')
     aux_docs = relationship('StationmetaAuxDoc', back_populates='station')
diff --git a/toardb/stationmeta/pydantic_toar_testing.py b/toardb/stationmeta/pydantic_toar_testing.py
index 4585aa257366ecd1f3e81e0625e50cd7751090d2..ab49149671138e4f4faf5b86375780f57951c99d 100644
--- a/toardb/stationmeta/pydantic_toar_testing.py
+++ b/toardb/stationmeta/pydantic_toar_testing.py
@@ -26,13 +26,10 @@ class StationmetaCoreBase(BaseModel):
     coordinates: Coordinates
     country: str
     state: str
-    coordinate_validation_status: int
-    coordinate_validation_date: dt.datetime
     type_of_environment: int
     type_of_area: int
     timezone: str
     additional_metadata: Json
-    coordinate_validator_id: int
 
     class Config(BaseConfig):
         arbitrary_types_allowed = True
@@ -55,12 +52,9 @@ external_data_toar = {
     "coordinates":{"lat":36.256,"lng":17.106,"alt":1534.0},
     "country":"China",
     "state":"Shandong Sheng",
-    "coordinate_validation_status":0,
-    "coordinate_validation_date":"2020-03-11T12:22:18.047974+01:00",
     "type_of_environment":0,
     "type_of_area":0,
     "timezone":"",
-    "coordinate_validator_id": 1,
     "additional_metadata": {}
 }
 
diff --git a/toardb/stationmeta/test_stationmeta.py b/toardb/stationmeta/test_stationmeta.py
index 6d44513d3dc2e06e82aea954aaa967f77e819198..c1ef93abaebce26b89c525022dba699fe2a81208 100644
--- a/toardb/stationmeta/test_stationmeta.py
+++ b/toardb/stationmeta/test_stationmeta.py
@@ -100,21 +100,18 @@ class TestApps:
 ##      expected_resp = [{'id': 1, 'codes': ['China11'], 'name': 'Mount Tai',
 ##                        'coordinates': {'lat': 36.256, 'lng': 117.106, 'alt': 1534.0},
 ##                        'country': 'China', 'state': 'Shandong Sheng',
-##                        'coordinate_validation_status': 0, 'coordinate_validation_date': '2020-02-28T12:27:03.746260+01:00',
 ##                        'type_of_environment': 0, 'type_of_area': 0, 'timezone': '',
-##                        'additional_metadata': {}, 'coordinate_validator_id': 1},
+##                        'additional_metadata': {}},
 ##                       {'id': 2, 'codes': ['SDZ54421'], 'name': 'Shangdianzi',
 ##                        'coordinates': {'lat': 40.65, 'lng': 117.106, 'alt': 293.9},
 ##                        'country': 'China', 'state': 'Beijing Shi',
-##                        'coordinate_validation_status': 0, 'coordinate_validation_date': '2020-02-28T12:27:03.746260+01:00',
 ##                        'type_of_environment': 0, 'type_of_area': 0, 'timezone': '',
-##                        'additional_metadata': {}, 'coordinate_validator_id': 1},
+##                        'additional_metadata': {}},
 ##                       {'id': 3, 'codes': ['China_test8'], 'name': 'Test_China',
 ##                        'coordinates': {'lat': 36.256, 'lng': 117.106, 'alt': 1534.0},
 ##                        'country': 'China', 'state': 'Shandong Sheng',
-##                        'coordinate_validation_status': 0, 'coordinate_validation_date': '2020-03-11T12:22:18.047974+01:00',
 ##                        'type_of_environment': 0, 'type_of_area': 0, 'timezone': '',
-##                        'additional_metadata': {}, 'coordinate_validator_id': 1}]
+##                        'additional_metadata': {}}]
 ##      assert response.json() == expected_resp
 
 
@@ -124,8 +121,6 @@ class TestApps:
 #       assert response.status_code == expected_status_code
 #       expected_resp = [OrderedDict([('codes', ['China11']), ('name', 'Mount Tai'), ('country', 'China'),
 #                                     ('state', 'Shandong Sheng'), ('coordinates', 'SRID=4326;POINT Z (17.106 36.256 1534)'),
-#                                     ('coordinate_validation_status', 'not checked'), ('coordinate_validator', 'sschroeder'),
-#                                     ('coordinate_validation_date', '2020-03-11T11:22:18.047000Z'),
 #                                     ('roles', [OrderedDict([('rolecode', 'PointOfContact'), ('person', 'Sabine Schröder <s.schroeder@fz-juelich.de>'), ('status', 'active')])]),
 #                                     ('meta_global', None), ('additional_metadata', {}),
 #                                     ('stationmetaauxurl', []), ('stationmetaauxdoc', []), ('stationmetaauximage', []), ('annotations', [])])]
@@ -138,10 +133,10 @@ class TestApps:
         assert response.status_code == expected_status_code
         expected_resp = {'id': 3, 'codes': ['China_test8'], 'name': 'Test_China',
                          'coordinates': {'lat': 36.256, 'lng': 117.106, 'alt': 1534.0},
-                         'country': 'China', 'state': 'Shandong Sheng', 'coordinate_validation_status': 'NotChecked',
-                         'coordinate_validation_date': '2020-03-11T12:22:18.047974+01:00', 'type_of_environment': 'Unknown',
+                         'country': 'China', 'state': 'Shandong Sheng',
+                         'type_of_environment': 'Unknown',
                          'type_of_area': 'Unknown', 'timezone': '',
-                         'additional_metadata': {}, 'coordinate_validator_id': 1}
+                         'additional_metadata': {}}
         assert response.json() == expected_resp
 
 
@@ -151,10 +146,10 @@ class TestApps:
         assert response.status_code == expected_status_code
         expected_resp = {'id': 3, 'codes': ['China_test8'], 'name': 'Test_China',
                          'coordinates': {'lat': 36.256, 'lng': 117.106, 'alt': 1534.0},
-                         'country': 'China', 'state': 'Shandong Sheng', 'coordinate_validation_status': 'NotChecked',
-                         'coordinate_validation_date': '2020-03-11T12:22:18.047974+01:00', 'type_of_environment': 'Unknown',
+                         'country': 'China', 'state': 'Shandong Sheng',
+                         'type_of_environment': 'Unknown',
                          'type_of_area': 'Unknown', 'timezone': '',
-                         'additional_metadata': {}, 'coordinate_validator_id': 1,
+                         'additional_metadata': {},
                          'roles': [], 'annotations': [], 'aux_images': [], 'aux_docs': [],
                          'aux_urls': [], 'globalmeta': None, 'globalservice': None}
         assert response.json() == expected_resp
@@ -182,20 +177,19 @@ class TestApps:
                 json={"stationmeta":
                           {"codes":["ttt3","ttt4"],
                            "name":"Test_China","coordinates":{"lat":36.256,"lng":117.106,"alt":1534.0},
-                           "country":"China","state":"Shandong Sheng","coordinate_validation_status":"NotChecked",
-                           "coordinate_validation_date":"2020-03-11T12:22:18.047974+01:00",
+                           "country":"China","state":"Shandong Sheng",
                            "type_of_environment":"Unknown","type_of_area":"Unknown","timezone":"",
-                           "coordinate_validator_id": 1, "additional_metadata":"{}"}
+                           "additional_metadata":"{}"}
                      }
                    )
         expected_status_code = 200
         assert response.status_code == expected_status_code
         expected_resp = {'id': 4, 'codes': ['ttt3','ttt4'], 'name': 'Test_China',
                          'coordinates': {'lat': 36.256, 'lng': 117.106, 'alt': 1534.0},
-                         'country': 'China', 'state': 'Shandong Sheng', 'coordinate_validation_status': 'NotChecked',
-                         'coordinate_validation_date': '2020-03-11T12:22:18.047974+01:00', 'type_of_environment': 'Unknown',
+                         'country': 'China', 'state': 'Shandong Sheng'
+                         'type_of_environment': 'Unknown',
                          'type_of_area': 'Unknown', 'timezone': '',
-                         'additional_metadata': {}, 'coordinate_validator_id': 1,
+                         'additional_metadata': {}
                          'roles': [], 'annotations': [], 'aux_images': [], 'aux_docs': [], 'aux_urls': [],
                          'globalmeta': None, 'globalservice': None}
         assert response.json() == expected_resp
@@ -206,10 +200,9 @@ class TestApps:
                 json={"stationmeta":
                           {"codes":["China11"],
                            "name":"Test_China","coordinates":{"lat":36.256,"lng":117.106,"alt":1534.0},
-                           "country":"China","state":"Shandong Sheng","coordinate_validation_status":"NotChecked",
-                           "coordinate_validation_date":"2020-03-11T12:22:18.047974+01:00",
+                           "country":"China","state":"Shandong Sheng",
                            "type_of_environment":"Unknown","type_of_area":"Unknown","timezone":"",
-                           "coordinate_validator_id": 1, "additional_metadata":"{}"}
+                           "additional_metadata":"{}"}
                      }
                    )
         expected_status_code = 400
diff --git a/toardb/test_toardb.py b/toardb/test_toardb.py
index 48b9f3b4838a1cf36f2556c613c40cf07475c360..be76f07681437f4a705014ad1efbcfc06108381c 100644
--- a/toardb/test_toardb.py
+++ b/toardb/test_toardb.py
@@ -146,6 +146,13 @@ class TestApps:
                                           [12,"NotCheckedPreliminary","not checked preliminary"],
                                           [13,"Changed","changed"],
                                           [14,"Estimated","estimated"],
-                                          [15,"MissingValue","missing value"]]}
+                                          [15,"MissingValue","missing value"]],
+                         "CL_vocabulary":[[0,"Created","created"],
+                                          [1,"SingleValue","single value correction in metadata"],
+                                          [2,"Comprehensive","comprehensive metadata revision"],
+                                          [3,"Typo","typographic correction of metadata"],
+                                          [4,"UnspecifiedData","unspecified data value corrections"],
+                                          [5,"Replaced","replaced data with a new version"],
+                                          [6,"Flagging", "data value flagging"]]}
         assert response.json() == expected_resp
 
diff --git a/toardb/timeseries/models.py b/toardb/timeseries/models.py
index 4f2616371ebf8fb3fac2a8b733ab10ad10049810..19cbb5214132047867ebf1793827cfe42d580e40 100644
--- a/toardb/timeseries/models.py
+++ b/toardb/timeseries/models.py
@@ -2,6 +2,7 @@ from .models_core import Timeseries
 from .models_role import TimeseriesRole, timeseries_timeseries_roles_table
 from .models_annotation import TimeseriesAnnotation, timeseries_timeseries_annotations_table
 from .models_programme import TimeseriesProgramme
+from .models_changelog import TimeseriesChangelog
 from toardb.base import Base
 
 from sqlalchemy import Table, Column, Integer, String
diff --git a/toardb/timeseries/models_changelog.py b/toardb/timeseries/models_changelog.py
new file mode 100644
index 0000000000000000000000000000000000000000..c4ac170754c34ec827c7f8dcceaae3ee7a5fe38e
--- /dev/null
+++ b/toardb/timeseries/models_changelog.py
@@ -0,0 +1,71 @@
+# coding: utf-8
+"""
+class TimeseriesChangelog(Base)
+===============================
+"""
+from sqlalchemy import Column, DateTime, ForeignKey, BigInteger, String, CHAR, \
+                       Text, Table, Sequence
+from sqlalchemy.orm import relationship
+from .models_core import Timeseries
+from toardb.auth_user.models import AuthUser
+from toardb.base import Base
+
+TIMESERIES_CHANGELOG_ID_SEQ = Sequence('timeseries_changelog_id_seq')  # define sequence explicitly
+class TimeseriesChangelog(Base):
+    """ Table "public.timeseries_changelog"
+
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------+
+    |     Column     |           Type           | Collation | Nullable |                      Default                     |
+    +================+==========================+===========+==========+==================================================+
+    | id             | bigint                   |           | not null | nextval('timeseries_changelog_id_seq'::regclass) |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------+
+    | datetime       | timestamp with time zone |           | not null |                                                  |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------+
+    | timeseries_id  | bigint                   |           | not null |                                                  |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------+
+    | type_of_change | integer                  |           | not null |                                                  |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------+
+    | description    | text                     |           | not null |                                                  |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------+
+    | old_value      | character varying(256)   |           | not null |                                                  |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------+
+    | new_value      | character varying(256)   |           | not null |                                                  |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------+
+    | period_start   | timestamp with time zone |           |          |                                                  |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------+
+    | period_end     | timestamp with time zone |           |          |                                                  |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------+
+    | version        | character(28)            |           |          |                                                  |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------+
+    | author_id      | integer                  |           | not null |                                                  |
+    +----------------+--------------------------+-----------+----------+--------------------------------------------------+
+    Indexes:
+     "timeseries_changelog_pkey" PRIMARY KEY, btree (id)
+    Foreign-key constraints:
+     "timeseries_changelog_author_id_fk_auth_user_id" FOREIGN KEY (author_id) REFERENCES auth_user(id)
+     "timeseries_changelog_timeseries_id_fk_timeseries_id" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id)
+     "timeseries_changelog_type_of_change_fk_cl_vocabulary_enum_val" FOREIGN KEY (type_of_change) REFERENCES cl_vocabulary(enum_val)
+    """
+
+    __tablename__ = 'timeseries_changelog'
+
+    id = Column(BigInteger, TIMESERIES_CHANGELOG_ID_SEQ, primary_key=True, server_default=TIMESERIES_CHANGELOG_ID_SEQ.next_value())
+    datetime = Column(DateTime(True), nullable=False)
+    description = Column(Text, nullable=False)
+    old_value = Column(String(256), nullable=False)
+    new_value = Column(String(256), nullable=False)
+    period_start = Column(DateTime(True))
+    period_end = Column(DateTime(True))
+    version = Column(CHAR(28))
+# do not use string declaration here (not working for pytest)
+# use the explicit class name here,
+# see: https://groups.google.com/forum/#!topic/sqlalchemy/YjGhE4d6K4U
+    timeseries_id = Column(ForeignKey(Timeseries.id), nullable=False)
+    author_id = Column(ForeignKey(AuthUser.id), nullable=False)
+# still to check for some pytest solution for controlled vocabulary
+    type_of_change = Column(ForeignKey('cl_Vocabulary.enum_val'), nullable=False)
+
+    author = relationship('AuthUser')
+    timeseries = relationship('Timeseries')
+    
+#   cl_vocabulary = relationship('ClVocabulary')
diff --git a/toardb/timeseries/test_timeseries.py b/toardb/timeseries/test_timeseries.py
index 0fad17edc96ba71b20028f2613072a28ae3ef014..796ea1cbd94cce2ebf67d9bbaeda9f72ddc1a99f 100644
--- a/toardb/timeseries/test_timeseries.py
+++ b/toardb/timeseries/test_timeseries.py
@@ -154,8 +154,8 @@ class TestApps:
                                        'cf_standardname': 'mole_fraction_of_toluene_in_air', 'units': 'nmol mol-1',
                                        'chemical_formula': 'C7H8', 'id': 7},
                           'station': {'additional_metadata': '{}', 'type_of_area': 0,
-                                      'coordinate_validation_date': '2020-02-28T12:27:03.746260+01:00', 'country': 'China',
-                                      'codes': ['SDZ54421'], 'coordinate_validation_status': 0, 'coordinate_validator_id': 1,
+                                      'country': 'China',
+                                      'codes': ['SDZ54421'],
                                       'timezone': '', 'type_of_environment': 0, 'state': 'Beijing Shi', 'name': 'Shangdianzi', 'id': 2},
                           'programme': {'id': 0, 'name': '', 'longname': '', 'homepage': '', 'description': ''}}]
         assert response.json() == expected_resp
@@ -183,8 +183,8 @@ class TestApps:
                                       'cf_standardname': 'mole_fraction_of_toluene_in_air', 'units': 'nmol mol-1',
                                       'chemical_formula': 'C7H8', 'id': 7},
                          'station': {'additional_metadata': '{}', 'type_of_area': 0,
-                                     'coordinate_validation_date': '2020-02-28T12:27:03.746260+01:00', 'country': 'China',
-                                     'codes': ['SDZ54421'], 'coordinate_validation_status': 0, 'coordinate_validator_id': 1,
+                                     'country': 'China',
+                                     'codes': ['SDZ54421'],
                                      'timezone': '', 'type_of_environment': 0, 'state': 'Beijing Shi', 'name': 'Shangdianzi', 'id': 2},
                          'programme': {'id': 0, 'name': '', 'longname': '', 'homepage': '', 'description': ''}}
         assert response.json() == expected_resp
@@ -234,9 +234,8 @@ class TestApps:
                                       'cf_standardname': 'mole_fraction_of_toluene_in_air', 'units': 'nmol mol-1',
                                       'chemical_formula': 'C7H8', 'id': 7},
                          'station': {'additional_metadata': '{}', 'type_of_area': 0,
-                                     'coordinate_validation_date': '2020-02-28T12:27:03.746260+01:00',
-                                     'country': 'China', 'codes': ['SDZ54421'], 'coordinate_validation_status': 0,
-                                     'coordinate_validator_id': 1, 'timezone': '', 'type_of_environment': 0,
+                                     'country': 'China', 'codes': ['SDZ54421'],
+                                     'timezone': '', 'type_of_environment': 0,
                                      'state': 'Beijing Shi', 'name': 'Shangdianzi', 'id': 2},
                          'programme': {'id': 0, 'name': '', 'longname': '', 'homepage': '', 'description': ''}}
         assert response.json() == expected_resp
@@ -273,9 +272,8 @@ class TestApps:
                                       'cf_standardname': 'mole_fraction_of_toluene_in_air', 'units': 'nmol mol-1',
                                       'chemical_formula': 'C7H8', 'id': 7},
                          'station': {'additional_metadata': '{}', 'type_of_area': 0,
-                                     'coordinate_validation_date': '2020-02-28T12:27:03.746260+01:00',
-                                     'country': 'China', 'codes': ['SDZ54421'], 'coordinate_validation_status': 0,
-                                     'coordinate_validator_id': 1, 'timezone': '', 'type_of_environment': 0,
+                                     'country': 'China', 'codes': ['SDZ54421'],
+                                     'timezone': '', 'type_of_environment': 0,
                                      'state': 'Beijing Shi', 'name': 'Shangdianzi', 'id': 2},
                          'programme': {'id': 0, 'name': '', 'longname': '', 'homepage': '', 'description': ''}}
         assert response.json() == expected_resp
diff --git a/toardb/toardb.py b/toardb/toardb.py
index 01a94469b740a677c8f7395e251d80961fa3a573..ca457c4a707f6c6c5d53edef98edb432579e323f 100644
--- a/toardb/toardb.py
+++ b/toardb/toardb.py
@@ -39,6 +39,7 @@ async def info():
         "Station Dominant Landcover Types": settings.DL_vocab,
         "Result Types": settings.RT_vocab,
         "Data Flags": settings.DF_vocab,
+        "Type of Change": settings.CL_vocab,
     }
     return controlled_vocabulary
 
@@ -62,6 +63,7 @@ async def info(name: str):
         "Station Dominant Landcover Types": settings.DL_vocab,
         "Result Types": settings.RT_vocab,
         "Data Flags": settings.DF_vocab,
+        "Type of Change": settings.CL_vocab,
     }
     return controlled_vocabulary[name]
 
@@ -132,6 +134,7 @@ async def startup_event():
     DL_vocabulary = __get_enum_dict(fake_cur, "dl_vocabulary")
     RT_vocabulary = __get_enum_dict(fake_cur, "rt_vocabulary")
     DF_vocabulary = __get_enum_dict(fake_cur, "df_vocabulary")
+    CL_vocabulary = __get_enum_dict(fake_cur, "cl_vocabulary")
 
 
 Enumdict=namedtuple("Dict",["value","string","display_str"])
@@ -154,6 +157,7 @@ TR_vocabulary = __get_enum_dict(fake_cur, "tr_vocabulary")
 DL_vocabulary = __get_enum_dict(fake_cur, "dl_vocabulary")
 RT_vocabulary = __get_enum_dict(fake_cur, "rt_vocabulary")
 DF_vocabulary = __get_enum_dict(fake_cur, "df_vocabulary")
+CL_vocabulary = __get_enum_dict(fake_cur, "cl_vocabulary")
 
 
 class Settings(BaseSettings):
@@ -175,6 +179,7 @@ class Settings(BaseSettings):
     DL_vocab = DL_vocabulary
     RT_vocab = RT_vocabulary
     DF_vocab = DF_vocabulary
+    CL_vocab = CL_vocabulary
 
 settings = Settings()