diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 642ed97cb48cdc7749e4bc0db8c943e1486abd96..e93c90f9de4deefb1dd0fc6ed8a71b774e888d60 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,7 +2,7 @@ image: docker:19.03.12
 
 variables:
   DOCKER_TLS_CERTDIR: "/certs"
-  IMAGE_VER: 1.11.0
+  IMAGE_VER: 1.12.0
 
 services:
   - docker:19.03.12-dind
diff --git a/lib/CF/Schema/Result/Event.pm b/lib/CF/Schema/Result/Event.pm
new file mode 100644
index 0000000000000000000000000000000000000000..3c2799dd7e6208d32165386d6297eadc12ef3a3b
--- /dev/null
+++ b/lib/CF/Schema/Result/Event.pm
@@ -0,0 +1,46 @@
+package CF::Schema::Result::Event;
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+our $VERSION = 1;
+
+__PACKAGE__->table('events');
+
+__PACKAGE__->add_columns(
+    id => {
+        data_type         => 'integer',
+        is_auto_increment => 1,
+        is_nullable       => 0,
+        sequence          => 'uid_seq'
+    },
+    qw(
+        uuid
+        type
+        owner_id
+        start
+        finish
+        name
+        description
+        organizer
+        stream_url
+    ),
+);
+
+__PACKAGE__->belongs_to(
+    user => 'CF::Schema::Result::User',
+    {
+        'foreign.id' => 'self.owner_id',
+    },
+);
+
+__PACKAGE__->has_many(
+    acls => 'CF::Schema::Result::EventACL',
+    { 'foreign.event_id' => 'self.id', },
+);
+
+__PACKAGE__->set_primary_key('id');
+
+1;
diff --git a/lib/CF/Schema/Result/EventACL.pm b/lib/CF/Schema/Result/EventACL.pm
new file mode 100644
index 0000000000000000000000000000000000000000..8dc9dcff5549e65808b7e0316df2b66598328987
--- /dev/null
+++ b/lib/CF/Schema/Result/EventACL.pm
@@ -0,0 +1,34 @@
+package CF::Schema::Result::EventACL;
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+our $VERSION = 1;
+
+__PACKAGE__->table('events_acl');
+
+__PACKAGE__->add_columns(
+    id => {
+        data_type         => 'integer',
+        is_auto_increment => 1,
+        is_nullable       => 0,
+        sequence          => 'uid_seq'
+    },
+    qw(
+        event_id
+        subject_class
+        subject
+        role
+    ),
+);
+
+__PACKAGE__->belongs_to(
+    event => 'CF::Schema::Result::Event',
+    {
+        'foreign.id' => 'self.event_id',
+    },
+);
+
+1;
diff --git a/lib/CF/Schema/Result/ProgramEntry.pm b/lib/CF/Schema/Result/ProgramEntry.pm
index d1d26cbbea1c2fcbe571757ee9be1c096cf1867d..0e0f5fdc53858c4d4a0c54b5cad79da7e0e009ca 100644
--- a/lib/CF/Schema/Result/ProgramEntry.pm
+++ b/lib/CF/Schema/Result/ProgramEntry.pm
@@ -17,6 +17,7 @@ __PACKAGE__->add_columns(
         sequence          => 'uid_seq'
     },
     qw(
+        event_id
         number
         start
         finish
diff --git a/sql/8/up.sql b/sql/8/up.sql
new file mode 100644
index 0000000000000000000000000000000000000000..dc274eeb59d372b49009520e7eccccdff28f6f49
--- /dev/null
+++ b/sql/8/up.sql
@@ -0,0 +1,28 @@
+create table "events" (
+    "id" integer not null default nextval('uid_seq'),
+    "uuid" uuid not null, -- unique string
+    "type" smallint not null default 1, --1
+    "owner_id" integer not null,
+    "start" timestamp(0),
+    "finish" timestamp(0),
+    "name" text not null,
+    "description" text,
+    "organizer" text,
+    "stream_url" text, -- externi stream
+    primary key("id"),
+    unique("uuid"),
+    foreign key ("owner_id") references "users" ("id") on update cascade on delete restrict
+);
+
+create table "events_acl" (
+    "id" integer not null default nextval('uid_seq'),
+    "event_id" integer not null,
+    "subject_class" varchar(8) not null,
+    "subject" text not null,
+    "role" text,
+    primary key("id"),
+    unique("event_id", "subject_class", "subject"),
+    foreign key ("event_id") references "events" ("id") on update cascade on delete cascade
+);
+
+alter table "program" add column "event_id" integer;